INNER JOIN OR条件的查询优化

时间:2015-01-13 19:48:02

标签: sql-server indexing

我有以下查询运行得非常慢,并且我已经使用估算的执行计划将问题范围缩小到最终的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
)

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

请在此处查看我的回答:

What goes wrong when I add the Where clause?

您说您尝试在TableE上添加覆盖索引,涵盖numericCol和id。但是,我怀疑查询没有使用它。这就是你看表Spool的原因。

您希望强制查询使用覆盖索引,方法是使其成为表中唯一的索引,或者包含查询提示。这应该消除表Spool并加速嵌套循环。

TableB相同。如果正在使用的索引仅在Id上,则它不会帮助NumericCol上的嵌套循环。通过删除Id上的索引或查询提示来强制解决问题。