2017-03-16 4 views
0

以下のサンプルクエリは、私の主なクエリの一部です。以下のクエリでSORT演算子がコストの30%を消費していることがわかりました。T-SQLでの注文の回避

SORTを回避するには、インデックスを作成する必要があります。このコードを最適化する他の方法はありますか?

SELECT TOP 1 CONVERT(DATE, T_Date) AS T_Date 
FROM TableA 
WHERE ID = r.ID 
AND Status = 3 
AND TableA_ID >ISNULL((
         SELECT TOP 1 TableA_ID 
         FROM TableA 
         WHERE ID = r.ID 
          AND Status <> 3 
         ORDER BY T_Date DESC 
         ), 0) 
ORDER BY T_Date ASC 
+0

「T_Date」にインデックスを追加しますか? – Siyual

+1

'r'テーブルはどこですか? – Lamak

+0

@Lamak - このコードは、Selectカラム(Selectフィールドで使用される単一の値を生成するSubクエリ)の結果を生成しています。 – par181

答えて

0

はこれを試してみてください:

SELECT TOP 1 CONVERT(DATE, T_Date) AS T_Date 
FROM TableA a1 
LEFT JOIN (
    SELECT ID, MAX(TableA_ID) AS MaxAID 
    FROM TableA 
    WHERE Status <> 3 
    GROUP BY ID 
) a2 ON a2.ID = a1.ID AND a1.TableA_ID > coalesce(a2.MAXAID,0) 
WHERE a1.ID = r.ID AND a1.Status = 3 
ORDER BY T_Date ASC 

原因不明のrエイリアスと組み合わせてTOP 1の使用は私を心配します。ほとんどの場合、MUCHは、このデータをサブクエリで処理することを含まない(このデータがAPPLY操作用でない限り)結果を得るためのより良い方法です。

1

not existsではなく、並べ替えを使用できます。スカラー副問合せの代わりにCTEまたは導出表を使用することで、パフォーマンスが向上すると思います。

select * 
from r ... left outer join 
(
    select ID, min(t_date) as min_date from TableA t1 
    where status = 3 and not exists (
     select 1 from TableA t2 
     where t2.ID = t1.ID 
      and t2.status <> 3 and t2.t_date > t1.t_date 
    ) 
    group by ID 
) as md on md.ID = r.ID ... 

または

select * 
from r ... left outer join 
(
    select t1.ID, min(t1.t_date) as min_date 
    from TableA t1 left outer join TableA t2 
     on t2.ID = t1.ID and t2.status <> 3 
    where t1.status = 3 and t1.t_date < t2.t_date 
    group by t1.ID 
    having count(t2.ID) = 0 
) as md on md.ID = r.ID ... 

また、あなたがID列に頼っているように見えるが、それはそれらの値が何を意味するかは明らかではありません。私は基本的にそれを無視し、代わりに日付の列を使用しています。