2016-09-23 17 views
0

次のSQLを最適化するにはどうすればよいですか?いくつかの結合は不必要に2回実行されています。冗長LEFT JOIN - 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 <> ' 

(UNIONの後に)SQLの第二の部分は、私が(矢印でマークされたように)一つの追加LEFT JOINを持っていることを除いてほぼ同様です。私は、一般的なSQLをテーブルで置き換える別のテーブルを作成しようとしましたが、うまくいきませんでした。

+1

? UNION ALLを使用していないので、重複が削除され、最初のクエリは完全に無意味なものになります。これは、そのクエリのすべての行がすでに2番目のクエリに含まれているためです。最初のクエリを削除するだけで、まったく同じ結果が得られます。 –

+0

なぜ両方のクエリで区別したいのですか?UNIONはデフォルトで結果クエリで区別されます –

+1

私はSeanに同意します。2番目のクエリは最初のクエリの結果をすべて含みます。 JOINので結果は制限されません(あなたのAND t1.BEID = 100がWHERE t1.BEID = 100であることを前提としています)。そして、それらの結合のすべてからの列が、テーブル1のレコードセットを変更すると、一致するものが追加されます – Matt

答えて

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 

私の推測では、あなたはおそらくUserQueuesとユーザーのテーブルに参加するが、必要の一部が参加し、代わりのUSINGの(SELECT)必要がない場合もありますが、単純に追加することによって、あなたは組み合わせることができ、上記あなたが持っているものを取った場合または、UNIONなしで同じ結果を得るために行ったように。

0
  1. ユニオンを使用しているのとは異なり、ユニオンを使用しているわけではありません。

  2. ほとんどの場合、すべてのページをスキャンする必要がないため、Existsは一般的に検索が高速です。

だから私の最初の試みは、そのようなものになるだろう:あなたはすべての両方のクエリーが必要なのはなぜ

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 <> '')