我有以下查询运行得非常慢,并且我已经使用估算的执行计划将问题范围缩小到最终的INNER JOIN的OR条件。
SELECT
TableE.id
FROM
TableA WITH (NOLOCK)
INNER JOIN TableB WITH (NOLOCK)
ON TableA.[bid] = TableB.[id]
LEFT JOIN TableC WITH (NOLOCK)
ON TableB.[cid] = TableC.[id]
LEFT JOIN TableD WITH (NOLOCK)
ON TableA.[did] = TableD.[id]
INNER JOIN TableE WITH (NOLOCK)
ON TableD.[eid] = TableE.[id]
OR TableE.[numericCol] = TableB.[numericCol] -- commenting out this OR statement leads to large performance increase
WHERE
TableA.[id] = @Id
我在TableB上有以下索引:
CREATE UNIQUE NONCLUSTERED INDEX [IX_TableB_numericCol_id] ON [dbo].[TableB]
(
[numericCol] ASC,
[id] ASC
)
并在TableE上:
CREATE NONCLUSTERED INDEX [IX_TableE_numericCol] ON [dbo].[TableE]
(
[numericCol] ASC
)
有什么想法吗?
答案 0 :(得分:1)
请在此处查看我的回答:
What goes wrong when I add the Where clause?
您说您尝试在TableE上添加覆盖索引,涵盖numericCol和id。但是,我怀疑查询没有使用它。这就是你看表Spool的原因。
您希望强制查询使用覆盖索引,方法是使其成为表中唯一的索引,或者包含查询提示。这应该消除表Spool并加速嵌套循环。
TableB相同。如果正在使用的索引仅在Id上,则它不会帮助NumericCol上的嵌套循环。通过删除Id上的索引或查询提示来强制解决问题。