在标准 SQL 中,union all
不保证 a 的结果是任何顺序的。所以,像:
select 'A' as c union all select 'B'
可以以任何顺序返回两行(尽管实际上在我所知道的任何数据库上,“A”将出现在“B”之前)。
在 SQL Server 中,这变成了使用“串联”物理操作的执行计划。
我可以很容易地想象连接操作会扫描它的输入,返回任何有可用记录的输入。但是,我在网上找到了以下声明(此处):
查询处理器将按照运算符在计划中出现的顺序执行此计划,第一个是最上面的,最后一个是结束的。
问题:这在实践中是真的吗?这能保证是真的吗?
我没有在 Microsoft 文档中找到任何参考,说明输入是按顺序扫描的,从第一个到最后一个。另一方面,每当我尝试运行它时,结果表明输入确实是按顺序处理的。
有没有办法让引擎一次处理多个输入?我的测试(使用比常量复杂得多的表达式)是在支持并行的 8 核机器上进行的,并且大多数查询确实利用了并行性。
不,Microsoft 没有文档保证该行为,因此无法保证。
此外,假设 Simple Talk 文章是正确的,并且 Concatenation 物理运算符始终按照计划中显示的顺序处理输入(很可能是正确的),那么不能保证 SQL Server 将始终生成保持相同的计划查询文本和查询计划之间的顺序,你只是稍微好一点。
不过,我们可以进一步调查。如果查询优化器能够对串联运算符输入重新排序,则未记录的 DMV 中应该存在
sys.dm_exec_query_transformation_stats
与该优化相对应的行。在 SQL Server 2012 Enterprise Edition 上,这会产生 24 行。忽略与常量相关的转换的错误匹配,有一个与串联物理运算符
UNIAtoCON
(Union All to Concatenation)相关的转换。因此,在物理运算符级别,似乎一旦选择了连接运算符,它将按照其派生的逻辑 Union All 运算符的顺序进行处理。事实上,这并不完全正确。存在优化后重写,可以在基于成本的优化完成后对物理串联运算符的输入进行重新排序。一个示例发生在 Concatenation 受制于行目标时(因此首先从更便宜的输入中读取可能很重要)。有关详细信息,请参阅Paul White 的
UNION ALL
优化。后期物理重写在 SQL Server 2008 R2 之前(包括 SQL Server 2008 R2)仍然有效,但回归意味着它不再适用于 SQL Server 2012 及更高版本。已发布一个修复程序,在启用查询优化器修补程序(例如跟踪标志 4199)的情况下恢复 SQL Server 2014 及更高版本(不是 2012 年)的这种重写。
但是关于逻辑并集 All 运算符 (
UNIA
) 呢?有一个UNIAReorderInputs
转换,可以重新排序输入。还有两个物理运算符可以用来实现逻辑Union All,UNIAtoCON
和UNIAtoMERGE
(Union All to Merge Union)。因此,查询优化器似乎可以对 a 的输入重新排序
UNION ALL
;但是,它似乎不是一个常见的转换(UNIAReorderInputs
在我很容易访问的 SQL Server 上零使用。我们不知道优化器使用的情况UNIAReorderInputs
;尽管它肯定在计划指南或使用时使用计划提示用于强制使用上述行目标物理重新排序输入生成计划。Concatenation 物理运算符可以存在于计划的并行部分中。遇到一些困难,我能够使用以下查询生成具有并行连接的计划:
因此,从最严格的意义上说,物理串联运算符似乎总是以一致的方式处理输入(顶部第一,底部第二);但是,优化器可以在选择物理运算符之前切换输入的顺序,或者使用合并联合而不是串联。
根据Craig Freedman的说法,连接运算符的执行顺序是有保证的。
从他的博客文章查看MSDN 博客上的查询计划:
并从在线书籍Showplan 逻辑和物理运算符参考
社区维基回答:
我不知道您是否可以证明任何观察到的行为总是得到保证,一种或另一种方式,除非您可以制造一个反例。如果没有,解决结果返回顺序的方法当然是添加一个
ORDER BY
.我不知道是否有“修复”,或者是否需要修复,如果您可以证明在某些情况下查询是以不同的顺序处理的。
缺乏任何明确的官方文档向我表明你不应该依赖这个。这正是8 年前 SQL Server 2005 的优化器发布时让人们
ORDER BY
在视图中遇到麻烦的事情。GROUP BY
ORDER BY
有了较新版本的 SQL Server 中的所有新功能(即将推出更多功能),即使您认为您今天可以保证特定的行为,我也不希望它成立(除非有文档证明这样做)。
即使您不依赖这种行为,您将如何处理结果?无论如何,我不会称一个局外人官员的简单谈话文章。据我们所知,这只是基于观察的猜测。
微软永远不会发布官方文档说“x”不能保证做“y”。这是我们在将近十年后仍然难以说服人们他们不能依赖观察到的订购的原因之一
ORDER BY
——没有说明“它不能保证”的文档。