2017-02-17 79 views
2

我需要運行查詢來比較兩個表並返回不在第二個表中的記錄。棘手的部分是兩個表之間的鏈接是有條件的。我有多個數據源輸入表2,然後輸入表1。我試過使用一個連接,但是這並不比我下面提到的要快。這些表格中有大約5萬條記錄。該查詢大約需要1.5分鐘才能完成。我希望能把它弄到幾秒鐘。表1和表2已經在這些字段上有索引。數據庫在兼容級別SQL2008上運行。使用條件連接優化SQL查詢

此查詢時間約1.5分鐘:

select * 
from Table1 t1 
where not exists (select * 
        from Table2 t2 
        where t2.seedID = case t2.SeedSource when 'SeedSource1' then t1.SeedSource1 
                 when 'SeedSource2' then t1.SeedSource2 
                 when 'SeedSource3' then t1.SeedSource3 
                 when 'SeedSource4' then t1.SeedSource4 
                 when 'SeedSource5' then t1.SeedSource5 end) 

此查詢需要5分鐘以上:

select d.* 
from Tabel1 t1 left join 
    Table2 t2 on t2.seedID = case t2.SeedSource when 'SeedSource1' then t1.SeedSource1 
               when 'SeedSource2' then t1.SeedSource2 
               when 'SeedSource3' then t1.SeedSource3 
               when 'SeedSource4' then t1.SeedSource4 
               when 'SeedSource5' then t1.SeedSource5 end 
where t2.seedID is NULL 

任何幫助將不勝感激。

+4

左右,這表是'M'和表是'd',他們怎麼知道't1'和't2'? – SqlZim

+0

您能否包含與問題相關的表結構的子集? –

+1

你有太多的別名來確定你正在嘗試完成什麼d,t1,t2,m –

回答

1

其實他們是不一樣的查詢作爲左連接將返回多行在多場比賽

不存在是更好的方法

我希望SeedSource,SeedSource1-5和seedID被索引

select * 
from Table1 t1 
where not exists (select * 
        from Table2 t2 
        where t2.seedID = t1.SeedSource1 
        and t2.SeedSource = 'SeedSource1' 
        union all 
        select * 
        from Table2 t2 
        where t2.seedID = t1.SeedSource2 
        and t2.SeedSource = 'SeedSource2' 
        //... 
       ) 

也許

left join Table2 t2 
    on (t2.seedID = t1.SeedSource1 and t2.SeedSource = 'SeedSource1') 
    or (t2.seedID = t1.SeedSource2 and t2.SeedSource = 'SeedSource2') 
    // ... 
+0

我沒有想到這樣做,但我會試試看。我不認爲ORS會比CASE聲明更好,但我們會看到。 TY –

+0

您的解決方案正在使用SeedSource1-5上的索引,所以我認爲兩者都更快。 – Paparazzi

+0

您獲得了UNION子查詢的勝利。這將查詢降低到大約20秒。 OR比我的第一個示例查詢需要更長的時間。謝謝! –

1

閱讀您的要求後,您的查詢看起來很好。 (這是最好的做法是使用Not Exists代替Not INLeft Join

你可以做一個小小的優化:

  • WHERE條款使用not exists (select 1 ...代替not exists (select * ...沒有必要選擇所有列當你可以選擇一個常數。 (更好的性能)

參考

+0

當使用exists()時,'select 1'和'select *'之間沒有** runtime **性能差異。儘管使用'select 1'將避免在查詢編譯期間檢查該表的任何不需要的元數據。 [EXISTS子查詢:SELECT 1 vs. SELECT - Conor Cunningham](http://www.sqlskills.com/blogs/conor/exists-subqueries-select-1-vs-select/) – SqlZim

0

可能:

SELECT t1.* FROM table1 t1 LEFT JOIN table2 t2 on t1.seedID = t2.seedID 
WHERE t2.seedID is NULL AND t1.SeedSource IN ('SeedSource1','SeedSource2','SeedSource3','SeedSource4','SeedSource5') 
+0

自t2開始,這不起作用。 SeedSource將永遠是這些值之一。最主要的是t2.SeedSource的值決定了t1中的哪些字段將用於連接這兩個表。另外,沒有t1.seedID。 –