或条件引起的内部联接性能问题

时间:2019-02-08 21:05:40

标签: sql sql-server query-performance stored-functions

我有一个sp,它返回3百万条记录。现在需要16分钟。我正在尝试对其进行优化。因为加入需要一定的时间。有什么办法可以优化它?

SELECT
    id, from
FROM
    [#Temp1] AD              
    JOIN [#Temp2]  SS
        ON AD.Id = SS.Id
        OR (SS.Code = AD.Code AND AD.ID IS NULL)        
JOIN wTable1 WSS WITH(NOLOCK)               
    ON SS.PId= WSS.Id

2 个答案:

答案 0 :(得分:1)

通常最好的方法是使用left join

select id, 
       coalesce(wss1.col, wss2.col) as col
from [#Temp1] AD left join            
     [#Temp2] SS1
     ON AD.Id = SS1.Id left join
     [#Temp2] SS2
     ON SS2.Code = AD.Code AND AD.ID IS NULL LEFT JOIN
     wTable1 WSS1            
     ON WSS1.Id = SS1.PID LEFT JOIN
     wTable1 WSS2
     ON WSS2.ID = SS2.PID
WHERE SS1.ID IS NOT NULL OR SS2.CODE IS NOT NULL;  -- one of the joins works  

我无法保证这会在您的特定情况下起作用,因为您尚未提供示例数据和所需的结果。但是,这种方法在类似情况下也可以使用。

答案 1 :(得分:1)

如可能的重复Is having an 'OR' in an INNER JOIN condition a bad idea?中所述,这将迫使计划具有嵌套循环,并经常用UNION替换它会带来收益(在这种情况下,UNION ALL是分支是互斥的) 。在下面的UNION ALL中,每个分支都可以使用哈希或合并联接,因为它们是直接的等价联接)

尚不清楚查询中每列来自哪个表,但基本方法是

WITH SS
     AS (SELECT SS.Id,
                SS.PId
         FROM   [#Temp1] AD
                JOIN [#Temp2] SS
                  ON AD.Id = SS.Id
         WHERE  AD.ID IS NOT NULL
         UNION ALL
         SELECT SS.Id,
                SS.PId
         FROM   [#Temp1] AD
                JOIN [#Temp2] SS
                  ON AD.Code = SS.Code
         WHERE  AD.ID IS NULL)
SELECT SS.Id,
       WSS.[from]
FROM   SS
       JOIN wTable1 WSS 
         ON SS.PId = WSS.Id