Snowflake SQL编译器和执行有多懒? [英] How lazy is the Snowflake SQL compiler and execution?

查看:29
本文介绍了Snowflake SQL编译器和执行有多懒?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以依赖Snowflake的懒惰评估来进行测试和引发异常吗?

CTE是否懒于评估?

这是否记录在案?

(相关问题:Assertions in Snowflake)

推荐答案

我想分享我自己在这方面的实验。懒惰评估对于优化目的非常有用,对于测试也非常有用。我找不到保证此行为的文档,因此这些实验有助于确定当前行为

引发测试异常

不会引发这些可能被0除以的异常:

select coalesce(1, 1/0), iff(true, 1, 1/0);

这在编写SQL脚本来验证结果时非常有用。例如,要验证查询是返回3行还是引发异常:

select iff(count(*)=3, 1, 1/0)
from (
    select * from values(1),(2),(3)
);

CTE优化

让我们来看看雪花是优化了CTE,还是无论如何都会评估它们:

with oh_no as (
  select 1/0 oh_no
), fine as (
  select 1 fine
)

select *
from fine
;

结果很好:CTE不会引发异常,因为不会计算它,因为它不是必需的。

极度懒惰

这是一个有趣的问题:

with oh_no as (
  select 1/0 oh_no
), fine as (
  select 1 fine
)

select *
from (
    select * from fine
    union all 
    select * from oh_no
)
limit 1
;

理论上应该从union抛出异常。但是Snowflake看到LIMIT 1已经过评估,它不会浪费时间处理更多行。

这意味着同一查询可能会引发错误,具体取决于处理行的顺序,如果处理初始行数满足查询要求,则不会引发错误。

但是所有这些示例都是常量?

正如@MatBailie注意到的那样,所有这些示例都是常量,因此可以在执行之前对其进行优化。

让我添加此示例来测试对实际表的查询结果:

select iff(count(*)=7, 1, 1/0)
from (
    select *
    from snowflake_sample_data.tpch_sf001.customer
    where c_phone like '18-8%'
);

不抛出异常,因为该表正好有7条记录与条件匹配。很好。

极端懒惰示例相同,实际数据:

with oh_no as (
    select 1/0 oh_no
), fine as (
    select c_custkey
    from snowflake_sample_data.tpch_sf001.customer
    where c_phone like '18-8%'
    limit 1
)

select *
from (
    select * from fine
    union all 
    select * from oh_no
)
limit 1
;

这篇关于Snowflake SQL编译器和执行有多懒?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆