我在 SQL Server 2008 R2 中有一个查询,格式如下:
SELECT TOP (2147483647) *
FROM (
SELECT *
FROM sub_query_a
) hierarchy
LEFT JOIN (
SELECT *
FROM sub_query_b
) expenditure
ON hierarchy.x = expenditure.x AND hierarchy.y = expenditure.y
ORDER BY hierarchy.c, hierarchy.d, hierarchy.e
子查询包含UNIONShierarchy和 INNER JOINS。expenditure子查询基于多个级别的子查询,并包含 UNIONS、INNER 和 LEFT JOINS,并最终包含 PIVOT 聚合。
hierarchy子查询本身在 2 秒内运行并返回 467 行。expenditure子查询本身在 7 秒内运行并返回 458 行。如果没有该子句,ORDER BY查询将在 11 秒内运行。但是,使用该ORDER BY子句,查询将在 11分钟内运行。
实际执行计划揭示了不同之处。如果没有该ORDER BY子句,则 thehierarchy和expenditure子查询都运行一次,结果将Merge Join (Right Outer Join)连接在一起。当ORDER BY包含该子句时,hierarchy查询仍会运行一次,但该expenditure部分从层次结构查询中的每行运行一次,并将结果Nested Loops (Left Outer Join)连接在一起。好像该ORDER BY子句导致expenditure子查询成为相关子查询(事实并非如此)。
为了验证 SQL Server 确实能够在 11 秒内执行查询并生成排序结果集,作为测试,我创建了一个临时表并将不带子句ORDER BY的查询结果插入其中。然后我做了一个SELECT * FROM #temp_table ORDER BY c, d, e。整个脚本花费了预期的 11 秒,并返回了预期的结果。
我想使查询与ORDER BY子句作为一个查询有效地工作——我不想仅仅为了启用#temp_table hacky 解决方案而创建一个存储过程。
关于此问题的原因或解决方法的任何想法?