2011-08-30 146 views
1

我有以下查詢其運行緩慢:問題的SQL Server查詢

WITH AcdTran 
    AS (select SequenceNo, 
       ReqID, 
       PolNumber, 
       transaction_id, 
       application_data, 
       trans_type, 
       retries, 
       status, 
       direction 
     from dbo.acord_transaction_benchmark with (nolock) 
     where direction = 'OUT') 
select top 1 * 
from AcdTran a 
where a.transaction_id = (select top 1 transaction_id 
          from AcdTran b 
          where b.PolNumber = a.PolNumber 
          order by ReqID, 
            SequenceNo, 
            transaction_id) 
     and (status = 'New' 
       or status = 'Resubmit') 
     and retries > 0 

我如何優化呢?跑得更快?

謝謝

+1

什麼是它應該做的?你的'select top 1 *'缺少一個'order by' –

+0

它應該按順序選擇一個新的狀態爲New或重新提交的記錄。所以,如果我有2個記錄的某個PolNumber,並且1有序列1,另一個有序列2,它應該選取序列1的那個。 – JustMe

+0

好吧,這只是一個標準的「最大n個每組」查詢,然後我認爲。有3種方法[在此評估](http://www.sqlmag.com/article/departments/optimizing-top-n-per-group-queries)。最好的使用取決於你的索引和數據分佈。 –

回答

2

應與窗口函數ROW_NUMBER更快:

WITH AcdTran AS (
     SELECT SequenceNo, 
       ReqID, 
       PolNumber, 
       transaction_id, 
       application_data, 
       trans_type, 
       retries, 
       status, 
       direction, 
       ROW_NUMBER() OVER(PARTITION BY transaction_id ORDER BY ReqID, SequenceNo, transaction_id) N 
      FROM dbo.acord_transaction_benchmark with (nolock) 
      WHERE direction = 'OUT') 
SELECT * 
    FROM AcdTran 
WHERE (status = 'New' 
      OR status = 'Resubmit') 
     AND retries > 0 
     AND N = 1; 

由於我沒有你的表結構也沒有任何數據,我明明沒有測試,所以你可能要修改查詢一下,但你有想法。

+0

好吧,這是返回,多個記錄。我只需要1條記錄.. – JustMe

+1

@JustMe - 你能否提供一些示例數據和期望的結果。 –

+0

JustMe:我的錯誤,它應該是'分區由transaction_id',我編輯我的帖子。 –

0

如果你拿出你的子查詢轉換爲連接:

WITH AcdTran 
    AS (select SequenceNo, 
       ReqID, 
       PolNumber, 
       transaction_id, 
       application_data, 
       trans_type, 
       retries, 
       status, 
       direction 
     from dbo.acord_transaction_benchmark with (nolock) 
     where direction = 'OUT') 
select top 1 * 
from AcdTran a 
inner join AcdTran b on a.SequenceNo = b.SequenceNo --or whatever the PK is 
where a.transaction_id = b.transaction_id and 
     a.PolNumber = b.PolNumber and 
     (a.status = 'New' or a.status = 'Resubmit') and 
     a.retries > 0 
order by b.ReqID, 
     b.SequenceNo, 
     b.transaction_id