冗余LEFT JOIN - SQL优化

时间:2016-09-23 20:57:22

标签: sql sql-server left-join query-optimization

如何优化以下SQL?有些连接被不必要地完成了两次。

SELECT DISTINCT
    t1.ID,
    t1.FirstName,
    t1.LastName

FROM Table1 t1
LEFT JOIN Table2 t2
    ON t2.LeadID = t1.ID
LEFT JOIN Table3 t3
    ON t2.someID = t3.someID
LEFT JOIN Table4 t4
    ON t4.UserID = t1.AgentID
LEFT JOIN Table5 t5
    ON t5.ProspectID = t1.ProspectID

WHERE (t1.ID IN (SELECT UserID FROM Users) OR t1.ID IS NULL)
AND t1.BEID = 100
AND t1.LastName <> ''
AND t1.FirstName <> ''


UNION


SELECT DISTINCT
    t1.ID,
    t1.FirstName,
    t1.LastName

FROM Table1 t1
LEFT JOIN Table2 t2
    ON t2.LeadID = t1.ID
LEFT JOIN Table3 t3
    ON t2.someID = t3.someID
LEFT JOIN Table4 t4
    ON t4.UserID = t1.AgentID
LEFT JOIN Table5 t5
    ON t5.ProspectID = t1.ProspectID
LEFT JOIN QueueMap uq
    ON uq.QueueID = t1.agentID  --<--- this is additional JOIN
    AND uq.QueueID IN (SELECT QueueID FROM UserQueues)
    AND t1.LastName <> ''
    AND t1.FirstName <> '

SQL的第二部分(在UNION之后)几乎相似,只是我有一个额外的LEFT JOIN(由箭头标记)。我已经尝试创建另一个表替换常用SQL与表,但它没有工作。

2 个答案:

答案 0 :(得分:0)

SELECT DISTINCT
    t1.ID,
    t1.FirstName,
    t1.LastName

FROM Table1 t1
LEFT JOIN Table2 t2
    ON t2.LeadID = t1.ID
LEFT JOIN Table3 t3
    ON t2.someID = t3.someID
LEFT JOIN Table4 t4
    ON t4.UserID = t1.AgentID
LEFT JOIN Table5 t5
    ON t5.ProspectID = t1.ProspectID
LEFT JOIN QueueMap uq
    ON uq.QueueID = t1.agentID  --<--- this is additional JOIN
    AND uq.QueueID IN (SELECT QueueID FROM UserQueues)
    AND t1.LastName <> ''
    AND t1.FirstName <> ''
WHERE
    ((t1.ID IN (SELECT UserID FROM Users) OR t1.ID IS NULL)
    AND t1.BEID = 100
    AND t1.LastName <> ''
    AND t1.FirstName <> '')

    OR uq.QueueID IS NOT NULL

我的猜测是你可能不需要一些连接而不是使用IN(SELECT)你可能需要加入UserQueues和Users表,但如果你拿走了上面的东西,你可以通过简单地添加一个OR来组合,因为我有为了在没有UNION的情况下获得相同的结果。

答案 1 :(得分:0)

  1. 我认为你不需要使用Union而不是Union all。

  2. 存在搜索速度通常更快,因为在大多数情况下不需要扫描所有页面。

  3. 所以我的第一次尝试就是这样:

    SELECT
        t1.ID,
        t1.FirstName,
        t1.LastName
    FROM 
        Table1 t1
        LEFT JOIN Table2 t2    ON t2.LeadID = t1.ID
        LEFT JOIN Table3 t3    ON t3.someID = t2.someID 
        LEFT JOIN Table4 t4    ON t4.UserID = t1.AgentID
        LEFT JOIN Table5 t5    ON t5.ProspectID = t1.ProspectID
    WHERE 
        ( ( EXISTS (SELECT 1 FROM Users where UserID = t1.ID ) ) 
            OR ( t1.ID IS NULL )
        )
        AND ( t1.BEID = 100 )
        AND ( t1.LastName <> '' )
        AND ( t1.FirstName <> '' )
    
    
    UNION
    
    
    SELECT
        t1.ID,
        t1.FirstName,
        t1.LastName
    
    FROM 
        Table1 t1
        LEFT JOIN Table2 t2    ON t2.LeadID = t1.ID
        LEFT JOIN Table3 t3    ON t3.someID = t2.someID 
        LEFT JOIN Table4 t4    ON t4.UserID = t1.AgentID
        LEFT JOIN Table5 t5    ON t5.ProspectID = t1.ProspectID
        LEFT JOIN QueueMap uq  ON uq.QueueID = t1.agentID  --<--- this is additional JOIN
                                AND ( EXISTS (SELECT 1 FROM UserQueues WHERE QueueID = uq.QueueID ) )
                                AND ( t1.LastName <> '' )
                                AND ( t1.FirstName <> '' )