有一个相当复杂的SQL Server查询我已经尝试优化几个月了,尽管有多个索引添加(添加覆盖,非聚簇索引)和查询重构/更改,但执行需要很长时间。没有详细说明,执行计划如下。这里有什么东西可以跳到任何人身上,效率特别低或者差吗?我摆脱了所有关键的查找,似乎大量使用索引搜索,这就是为什么我感到困惑,它仍然需要花费大量的时间。查询运行时,瓶颈显然是CPU(不是磁盘I / O)。非常感谢任何想法。
答案 0 :(得分:0)
好的,所以我根据Martin的评论进行了更改,这些评论似乎极大地帮助了查询速度。我不是百分之百肯定这是解决方案bc我已经经常运行这么多,并且可能已经将如此多的底层数据放入内存中,现在它很快。但我认为实际上存在真正的差异。
具体来说,嵌套循环内部的3次扫描是由非常小的表上的子查询引起的,这些表包含要从结果集中完全排除的一小组记录。从概念上讲,查询类似于:
SELECT fields
FROM (COMPLEX JOIN)
WHERE id_field NOT IN (SELECT bad_ID_field FROM BAD_IDs)
这个想法是,如果记录出现在BAD_ID中,它就不应该包含在结果中。
我对此进行了修改并将其更改为:
SELECT fields
FROM (COMPLEX JOIN)
LEFT JOIN BAD_IDs ON id_field = bad_ID_field
WHERE BAD_IDs.bad_ID_field IS NULL
这在逻辑上是相同的 - 它排除了BAD_ID中任何ID的结果 - 但它使用连接而不是子查询。甚至执行计划也几乎相同; TOP操作变为树中其他位置的FILTER,但聚集索引扫描仍然存在。
但是,它似乎运行速度更快!这是预期的吗?我一直认为我所用的方式中使用的子查询是可以的,并且服务器将知道如何创建最快(并且可能是相同的,几乎是它)的执行计划。这不正确吗?
THX!