2011-07-21 88 views
3

我正在嘗試重構幾個舊的代碼段......我重構了下面的當前塊,並突出顯示了導致性能問題的NOT IN語句。我試圖用左外連接重寫NOT IN部分。SQL NOT IN可能的性能問題

任何人都可以幫助,或者如果可能的話建議更好的方法嗎?

SELECT 
    left(unique_id,16) AS casino_id , 
    right(unique_id,24) AS game_id 
FROM ( 
     SELECT 
      distinct o.casino_id + g.game_id AS unique_id  
     FROM 
      game g INNER JOIN Bet b 
      ON g.game_id = b.game_id 
      INNER JOIN CasinoUser u 
      ON b.user_id = u.user_id 
      INNER JOIN onewalletcasino o 
      ON u.casino_id = o.casino_id 
     WHERE 
      game_start between dateadd(mi, -180, getdate()) 
      and dateadd(mi, -5, getdate()) 
      and b.[status] <> 'P' 
    ) t 
WHERE 
    unique_id NOT in 
    (SELECT casino_id + game_id AS casino_id 
     FROM 
     thirdpartysettlecalled 
     WHERE 
     [status] = 'Y') 
ORDER BY casino_id 
+1

在最後一行我猜[狀態]也可以是'N',所以簡單地取出'NOT'並用'N'取代'Y',從而消除NOT? –

+6

我敢打賭0.01 $'NOT IN'不是問題。 –

+0

我一直在回答答案,投了一對夫婦,但我的評級沒有出現,認爲我沒有正確完成它,但我花時間感謝人們..也許你有太多的時間來寫這些評論,並提供沒有答案! –

回答

3

你有一列串聯防止任何使用索引

的嘗試NOT EXISTS將分別

SELECT distinct 
    o.casino_id, g.game_id 
FROM 
    game g 
    INNER JOIN 
    Bet b ON g.game_id = b.game_id 
    INNER JOIN 
    CasinoUser u ON b.user_id = u.user_id 
    INNER JOIN 
    onewalletcasino o ON u.casino_id = o.casino_id 
WHERE 
    game_start between dateadd(mi, -180, getdate()) 
         and dateadd(mi, -5, getdate()) 
    and 
    b.[status] <> 'P' 
    AND 
    NOT EXISTS (SELECT * 
      FROM 
       thirdpartysettlecalled tp 
      WHERE 
       tp.[status] = 'Y' 
       AND 
       tp.casino_id = o.casino_id AND tp.game_id = g.game_id) 
ORDER BY 
    casino_id 

支持2列之後,請檢查您的索引或課程......

這也是EXCEPT的一個很好的用法(ORDER BY最後像UNION一樣結束:感謝@Damien_The_Unbeliever)

SELECT distinct 
    o.casino_id, g.game_id 
FROM 
    game g 
    INNER JOIN 
    Bet b ON g.game_id = b.game_id 
    INNER JOIN 
    CasinoUser u ON b.user_id = u.user_id 
    INNER JOIN 
    onewalletcasino o ON u.casino_id = o.casino_id 
WHERE 
    game_start between dateadd(mi, -180, getdate()) 
         and dateadd(mi, -5, getdate()) 
    and 
    b.[status] <> 'P' 

EXCEPT 
SELECT tp.casino_id, tp.game_id 
FROM thirdpartysettlecalled tp 
WHERE tp.[status] = 'Y' 

ORDER BY 
    casino_id 
+0

不邏輯仍然使存在聲明的索引使用失效?或者只有在哪裏聲明? –

+0

相關的DBA問題:http://dba.stackexchange.com/questions/4009/the-use-of-not-logic-in-relation-to-indexes –

+1

(EXCEPT) - ORDER BY在整個結尾處與UNION一樣 –