【问题标题】:Does the Snowflake Query Optimiser respect CTEs?Snowflake 查询优化器是否尊重 CTE?
【发布时间】:2021-01-18 21:50:45
【问题描述】:

如果我编写一个包含 CTE 的 SQL 语句,查询优化器是否总是将这些 CTE 作为离散语句保留以单独优化,或者如果计算结果 SQL 会更快,它是否可以将这些 CTE 与整个 SQL 的其他部分合并执行?

这个问题是由另一个用户提出的问题触发的。他们在 CTE 中使用序列生成器;当 CTE SQL 单独运行时,它总是产生 12 个连续的数字,正如预期的那样。但是,当在 CTE 中作为更大 SQL 语句的一部分运行时,它缺少数字,即它没有产生连续的值。

这是大型数据集的一个已知问题/行为,但由于只有 12 个值,它不应该成为问题 - 但事实表明 CTE 没有按书面规定运行,有 12 条记录结果集随后连接到其他表,但查询优化器改写了整个查询并将 CTE 逻辑与 SQL 语句的其他部分合并,因此产生了更大的数据集。

【问题讨论】:

  • 使用 explain 查看 Snowflake 可能正在运行的内容。

标签: sql snowflake-cloud-data-platform common-table-expression


【解决方案1】:

Snowflake 没有提供很多关于它如何优化查询的解释。

我可以说,一般来说,处理 CTE 有两种方法:

  • 物化 CTE,使其运行一次,然后读取物化版本。
  • 将 CTE 逻辑合并到查询的其余部分并作为查询的一部分进行优化。

我实际上希望 Snowflake 能够两者,选择更好的执行计划,因为它是一个从数十年的优化经验中学习的现代数据库。在某些情况下,这两种方法都可能更好。

话虽如此,如果代码返回的数据如您所描述的那样发生变化,则存在错误。优化的重点不是改变代码的语义(意义)。重点是返回相同的结果,但使用不同的底层算法。

【讨论】:

  • 感谢您的信息。我猜它有点灰色地带:已知序列生成器的行为不会为大型数据集生成连续值;因此,在任何需要连续值的情况下使用它可能是一种风险。是在应该工作的地方编写 SQL,然后查询优化器重新编写它以生成你可以合理预期它不工作的 SQL、错误或编码陷阱?
  • @NickW。 . .如果您实际上使用的是sequence,那么您可能会遇到问题,因为这会产生副作用。如果您正在使用诸如row_number() 之类的函数,那么代码应该是安全的。
  • CTE 并不是 Snowflake 中的“操作顺序”。优化器利用它们来创建单个执行配置文件。当我认为 CTE 会按照 CTE 的顺序执行时,我已经看到了 CTE 的疯狂副作用,但实际上并非如此。例如,SEQ() 函数很奇怪。
猜你喜欢
  • 2021-12-12
  • 2023-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-10
  • 2011-06-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多