我在 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 解决方案而创建一个存储过程。
关于此问题的原因或解决方法的任何想法?