【问题标题】:SQL NOT IN possibly performance issuesSQL NOT IN 可能存在性能问题
【发布时间】:2011-07-21 09:54:16
【问题描述】:

我正在尝试重构几段旧代码...我已经重构了下面的当前代码,并突出显示了导致性能问题的 NOT IN 语句。我试图用左外连接重写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 

【问题讨论】:

  • 在最后一行我猜 [Status] 也可以是 'N' 所以只需取出 'NOT' 并将 'Y' 替换为 'N' 从而消除 NOT ?
  • 我赌 0.01 美元 NOT IN 不是问题。
  • 我一直在回复答案,投了几个票,但我的评分没有出现,认为我没有正确完成它,但我花时间感谢人们..也许你有点太多了是时候写这些 cmets 并且不提供任何答案了!
  • 侮辱那些会帮助你的人是不可行的。
  • @Chris Wood:我们黑猩猩可以用 Stackoverflow 积分换取食物颗粒或性好处。

标签: sql tsql sql-server-2008 subquery


【解决方案1】:

您有一个列连接,可以防止使用任何索引

尝试 NOT EXISTS 将分别支持 2 列

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 

然后,检查您的索引或课程...

这也是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

【讨论】:

  • NOT 逻辑是否仍然使使用存在语句的索引无效?还是仅在 where 语句中?
  • (EXCEPT) - ORDER BY 放在整个事情的结尾,就像 UNION 一样
  • @SBlackler:在 dba.se 上添加了答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-21
  • 2018-10-18
  • 1970-01-01
  • 1970-01-01
  • 2021-08-21
  • 2020-11-05
  • 1970-01-01
相关资源
最近更新 更多