如果存在需要"永远"当select语句需要1秒时

时间:2018-03-06 16:08:47

标签: sql sql-server tsql

我很好奇我所看到的。在我取消之前,此查询已运行了20分钟。

IF EXISTS
    (SELECT
        1
    FROM
        apm.Transactions as rTransactions
        left join
        apm.Transactions as cTransactions on rTransactions.Service_ID = cTransactions.Service_ID and cTransactions.Transaction_Type = 'c'
    WHERE
        rTransactions.processed = 0
        AND rTransactions.Transaction_Type in ('P','R','A')
        AND cTransactions.Transactions_ID IS NULL
    ) select 'Found a match'

但是,如果我只运行选择部分:

SELECT
        1
    FROM
        apm.Transactions as rTransactions
        left join
        apm.Transactions as cTransactions on rTransactions.Service_ID = cTransactions.Service_ID and cTransactions.Transaction_Type = 'c'
    WHERE
        rTransactions.processed = 0
        AND rTransactions.Transaction_Type in ('P','R','A')
        AND cTransactions.Transactions_ID IS NULL

将在1秒内完成。

当我将其更改为min(1)时,此查询也需要一秒钟:

-- IF EXISTS --removed this line b/c @honeybadger pointed out min(1) will alway return a result
IF 1 = 
    (SELECT
        min(1)
    FROM
        apm.Transactions as rTransactions
        left join
        apm.Transactions as cTransactions on rTransactions.Service_ID = cTransactions.Service_ID and cTransactions.Transaction_Type = 'c'
    WHERE
        rTransactions.processed = 0
        AND rTransactions.Transaction_Type in ('P','R','A')
        AND cTransactions.Transactions_ID IS NULL
    ) select 'Found a match'

我可以告诉执行计划的变化,但我不确定为什么会出现这种情况。让我觉得If存在并且选择1不是一种安全的方法。 enter image description here

1 个答案:

答案 0 :(得分:3)

NOT EXISTS可能表现更好

  SELECT 1
    FROM apm.Transactions as      rTransactions
    left join apm.Transactions as cTransactions 
      on rTransactions.Service_ID = cTransactions.Service_ID 
     and cTransactions.Transaction_Type = 'c'
   WHERE rTransactions.processed = 0
     AND rTransactions.Transaction_Type in ('P','R','A')
     AND cTransactions.Transactions_ID IS NULL

  SELECT 1
    FROM apm.Transactions as rTransactions
   WHERE rTransactions.processed = 0
     AND rTransactions.Transaction_Type in ('P','R','A')
     AND NOT EXISTS ( SELECT 1   
                        FROM apm.Transactions as cTransactions 
                       WHERE cTransactions.Service_ID = rTransactions.Service_ID   
                         and cTransactions.Transaction_Type = 'c' 
                    )