sql - Snowflake SQL 编译器和执行有多懒惰?
解决方案
我想在这方面分享我自己的实验。惰性评估对于优化目的和测试非常有用。我找不到承诺这种行为的文档,因此这些实验有助于确定当前行为
为测试抛出异常
这些潜在的除以 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优化
让我们看看 Snowflake 是否优化了 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
;
推荐阅读
- php - $request->all() 始终为空
- amazon-web-services - 如何对 AWS DynamoDB for AWS CLI 进行速率限制扫描?
- python - 清理不需要的scrapy结果行
- javascript - 如何在打字效果中显示输入的文本以及一些常量文本?
- spring-mvc - 即使我正在使用 Controller 注释,我也没有发现任何处理程序异常
- css - 字体显示未知属性 wordpress GoDaddy
- python - 使用 python 处理大型 excel 文件花费太多时间
- javascript - 为什么 React Redux 在触发时分派两次
- google-sheets - 如何计算 2 个非空单元格及其在 Google 表格中的中间空单元格之间的行数?
- python - 为什么要在构造函数中放置一个属性变量