SQL Server中UNION比UNION ALL快一倍?14万条数据场景求解
为何UNION比UNION ALL更快?
我实在搞不懂为什么会出现这么大的性能差异——按常识,不检查重复项的UNION ALL合并结果集的速度,怎么都不该慢于需要去重的UNION,甚至通常应该更快才对!
目前有两个视图,单独查询时,一个返回约78000条记录,另一个返回约63000条,各自耗时都在7秒左右。它们的查询语句完全相同,只是读取的表不一样(两张表的索引结构完全一致)。
合并视图测试
先执行了UNION ALL的版本:
SELECT * FROM v1 UNION ALL SELECT * FROM v2
这个查询返回141167行数据,耗时约14秒——数据量翻倍,时间也跟着翻倍,符合预期。
但出于好奇,我把UNION ALL换成了UNION,执行了完全相同的查询:
SELECT * FROM v1 UNION SELECT * FROM v2
结果意外发现,它同样返回141167行数据(说明两个视图的记录本身没有重复),但耗时却只有约7秒!
我本来因为两个视图的结果本身就唯一,一直用UNION ALL,可现在明明多做了不必要的去重操作,速度反而快了一倍,这到底是怎么回事?
执行计划差异
对比两者的执行计划,除了最后几步之外,其余部分完全一致。我对执行计划的理解不算深入,也不方便泄露敏感数据,只整理出核心差异:
UNION ALL的执行逻辑:串行执行两个视图的查询,先完成v1的查询,再执行v2的查询,最后直接合并结果返回。总耗时是两个视图单独查询的时间之和。UNION的执行逻辑:并行执行两个视图的查询,同时读取两张表的数据,之后通过排序完成去重(但因为实际无重复,去重开销极低),最终返回结果。并行执行把两个子查询的耗时重叠,总耗时接近单个视图的查询时间。
原因总结
SQL Server的查询优化器在处理UNION时,由于需要进行去重操作,会自动选择并行执行两个子查询;而UNION ALL因为不需要去重,优化器默认采用了串行执行策略。虽然UNION多了去重步骤,但并行执行带来的时间收益远超过去重的额外开销,最终总耗时反而比UNION ALL低了一倍。
内容的提问来源于stack exchange,提问作者Dominic
相关产品推荐
相关产品推荐

