2016-08-02 103 views
1

我有以下查詢SQL服務器優化問題

SELECT DISTINCT ColA,ColB AS S 
    from TableA 
    where ColA <> 0   
    AND CONCAT(ColA,ColB) NOT IN (
            SELECT DISTINCT CONCAT(ColA,ColB) from TableB 
            WHERE ColB <> 0 
           ) 

TableA大約有記錄200000

TableB有大約50000記錄

當我運行此查詢它花費太大約2分鐘時間。

如何優化此查詢以減少執行時間?

我該怎麼做才能優化這個查詢?

+3

請張貼執行計劃以XML,表架構有一些樣本數據 – TheGameiswar

+0

你有'可樂<> 0 2個AND和AND CONCAT' – vercelli

+1

是的cols號碼?你確定連接它們嗎? 'select select concat(a,b) from(select 11 as a,2 as b union all select 1,12)t 其中concat(a,b)='112' – Serg

回答

2

試試這個....

SELECT DISTINCT A.ColA, A.ColB AS S 
from TableA A 
where A.ColA <> 0 
AND NOT EXISTS (SELECT 1 
       from TableB B 
       WHERE B.ColB <> 0 
       AND A.ColA= B.ColA 
       AND A.ColB = B.ColB) 

我不知道很多關於你的表架構或索引,但我知道有一點可以肯定的是,表達CONCAT(ColA,ColB)不是可優化搜索。寫相同的查詢有點不同,如果在列ColAColB的列上存在索引,則會更快。

+0

理論上,您的查詢可能會帶來結果不正確。在你的情況下,'CONCAT(ColA,ColB)'將等於'CONCAT(ColB,ColA)',不是嗎? –

0

CONCAT將排除任何索引在您的列在兩個表中尋找。

如果您的查詢的主要目的是找到所有在TableA而非TableB中的ColA,ColB組合,您可以嘗試類似這樣的方法。

SELECT DISTINCT ColA,ColB AS S 
FROM TableA 
WHERE ColA <> 0 
AND NOT EXISTS(
    SELECT TOP 1 * FROM TableB 
    WHERE TableB.ColA = TableA.ColA 
    AND TableB.ColB = TableA.ColB 
    AND TableB.ColB <> 0 
    ) 

注:這將導致比當前的查詢但它很難不實際的執行計劃和現有的表結構和索引

0

使用set operation評論更好的執行計劃:

SELECT ColA, ColB FROM TableA WHERE ColA <> 0 
EXCEPT 
SELECT ColA, ColB FROM TableB WHERE ColB <> 0 

DISTINCT需要的原因EXCEPT無論如何這樣做。

0

你可以用這個查詢

SELECT DISTINCT ColA,ColB AS S 
FROM TableA LEFT OUTER JOIN TableB 
    ON TableA.ColA = TableB.ColA 
     and TableA.ColB = TableB.ColB 
WHERE TableA.ColA <> 0 
    and TableB.ColB <> 0 
    and TableB.ColB is null 
0

正如一些海報所指出的那樣,你將需要使用CONCAT而不是在可樂COLB進行查詢的獨立,以獲得正確的數據試試。

如果這是一個足夠重要的查詢值得自己的索引,或CONCAT(ColA,ColB)是常用的數據。您可以考慮爲CONCAT(ColA,ColB)和該計算列上的索引創建計算列。

SELECT DISTINCT 
    A.ColA, A.ColB 
    FROM TableA A 
    LEFT JOIN TableB B 
    ON B.CONCAT(ColA,ColB) = A.CONCAT(ColA,ColB) 
    WHERE A.ColA <> 0 
    and B.ColB <> 0 
    and B.ColB is null 

我也有運氣過濾使用CTE,然後做最後的任何計算,以充分利用目前在桌上的索引。

WITH FilteredA as (
    select ColA, ColB 
    from tableA 
    WHERE ColA <> 0), 

    FilteredB as (
    select ColA, ColB 
    from tableB 
    WHERE ColB <> 0) 

    SELECT DISTINCT FilteredA.* 
    from FilteredA 
    LEFT JOIN FilteredB ON FilteredA.ColA = FilteredB.ColB 
    AND FilteredA.ColB = FilteredB.ColB 
    WHERE FilteredA.CONCAT(ColA,ColB) = FilteredB.CONCAT(ColA,ColB)