2017-02-09 8 views
0

私はテーブルを持っており、約5百万行があります。このテーブルの条件付き並べ替えを試すと約25秒かかりますが、条件付き並べ替えを特定の並べ替え条件に変更すると1秒かかります。以下のような違いのみ。SQL Serverの条件付きソートのパフォーマンスの問題

--takes 1 second 
ROW_NUMBER() OVER (ORDER BY OrderId DESC) AS RowNumber 

--takes around 25 seconds 
CASE @SortColumn WHEN 'OrderId' THEN ROW_NUMBER() OVER (ORDER BY OrderId DESC) AS RowNumber 

このシナリオでは、SQLサーバーで何が起きているのですか?

+1

各状況でクエリプランを確認しましたか?違いは何ですか?あなたはその計画を投稿できますか? – strickt01

+0

ありがとう@ strickt01。違いはソートコストだけです。 – ihsany

答えて

0

OrderIdにインデックスを付ける必要があります。したがって、最初のインスタンスで:

ROW_NUMBER() OVER (ORDER BY OrderId DESC) AS RowNumber 

SQLはもともとOrderId列に索引スキャンを行ったソートを実行する必要はありません。索引は、注文する列によって順序付けされるので、別のソートを実行する必要はありません。

ただし、2番目の例では、SQLは各行に対してCASE @SortColumn WHEN 'OrderId' THEN ROW_NUMBER() OVER (ORDER BY OrderId DESC) ENDを評価する必要があります。したがって、各行に対してCompute Scalar演算を実行してCASEステートメントの結果を計算します。この操作の結果は、列を表していないため、さらにソート操作が必要なため、索引にマップすることはできません。 500万行を超えると、これは非常に高価な操作です。

あなたは非インデックス列を介してクエリを実行した場合:

--takes 25 second 
ROW_NUMBER() OVER (ORDER BY NonIndexedColumn DESC) AS RowNumber 

--takes around 25 seconds 
CASE @SortColumn WHEN 'NonIndexedColumn' THEN ROW_NUMBER() OVER (ORDER BY NonIndexedColumn DESC) AS RowNumber 

SQLは、両方のインスタンスでソートする必要があり(とちょうどソートインデックスを使用していない)と同じように、両方のクエリが、おそらく同じようにゆっくり実行します。したがって、列を並べ替えるために渡すことは、インデックスされていない列を選択した場合、多数の行にわたってパフォーマンスが低下することになります。したがって、ORDER BYが適用される前に、結果が管理可能な行に絞り込まれるようにする必要があります。

+0

もう一度@ strickt01に感謝します。 OrderId列はPKでインデックスがあります。私はあなたが各行に適用されるスカラー操作について正しいと思います。それは私にとって意味があります。 – ihsany

+0

私はこのパフォーマンスの問題を解決するためにいくつかの異なるアプローチを試みます。そうでなければ、動的SQLクエリのアプローチに戻ります。 – ihsany

関連する問題