4

ストアドプロシージャからページ化された結果を取得するために行番号を使用しています。

動的なcaseステートメントの列名を使用した順序付けは処理速度を低下させていることがわかりましたが、すべての順序をハードコーディングすれば問題ありません。

WHOLE sqlクエリを1つの文字列にすることなく、SP_EXECUTESQLを使用して、動的な順序を高速化する方法はありますか?

            ROW_NUMBER() OVER (ORDER BY 
            CASE WHEN @OrderByColumnName = 'IdentityValue' AND @OrderAscending  = 0 THEN CLH.IdentityValue END DESC,
            CASE WHEN @OrderByColumnName = 'IdentityValue' AND @OrderAscending  = 1 THEN CLH.IdentityValue END
            --CLH.CustomerName

            ) AS [ROW]
4

4 に答える 4

1

単一のクエリでパラメータ値に基づいて異なるインデックスを使用することは、SQLServerではサポートされていません。AFAIK、これには2つの解決策があります。

  • ストアドプロシージャで動的クエリを作成し、sp_executesql
  • 動的クエリクライアント側を構築する

実際には、PHPと.NETアプリケーションがコードを共有することは困難です。または、異なる.NETバージョンの場合でも。そのため、最初のオプションがより強力な選択肢になります。

したがって、これを行うための最良の方法は動的SQLを含みます。そして、ええ、それはかなり驚くべきことです。:)

于 2011-12-13T12:57:09.363 に答える
1

問題は、SQLServerがすべてのパラメーターに適合する1つの実行プランを構築しようとしていることです。これは、異なるパラメータを指定したときに、気が変わって別のインデックスを選択することはないことを意味します。(different index不適切なインデックスを並べ替える負荷が非常に高くなる可能性があるため、この部分は重要です。)

これを実現する唯一の方法は、新しい実行プランを生成することです。これには、動的SQLが含まれます。まさに避けたいことです。


でも; 動的SQLとSP_EXECUTESQLは必ずしも悪い考えではありません。パラメータ化することもできるため、正しく使用すると、実行プランを再利用でき、この種の問題に対して非常に効率的になります。

動的SQLを回避する必要がある特定の理由はありますか?


唯一の現実的な回避策は、クエリを複数回、異なる順序で書き出し、T-SQLIFブロックで使用するクエリを選択することです。これにより、オプティマイザーはさまざまな実行計画を生成できます。

于 2011-12-13T12:39:52.477 に答える
0

あなたが試みることができる1つのことはあなたの2つのcase節を1つのcaseに結合することです-このように:

(ORDER BY 
        CASE WHEN @OrderByColumnName = 'IdentityValue' AND @OrderAscending  = 0 
                 THEN CLH.IdentityValue*-1
             WHEN @OrderByColumnName = 'IdentityValue' AND @OrderAscending  = 1 
                 THEN CLH.IdentityValue 
        END
 )

明らかに、潜在的なソート値の一部が数値ではなく文字列である場合、このアプローチは実用的ではありません。

于 2011-12-13T12:56:16.170 に答える
0

並べ替えごとの処理が少なくなるように、複数のROW_NUMBERステートメントを試してください

   ROW_NUMBER() OVER (ORDER BY CLH.IdentityValue) DESC AS rnDesc,
   ROW_NUMBER() OVER (ORDER BY CLH.IdentityValue) AS rnAscDesc,
   ...
ORDER BY
   CASE WHEN @OrderByColumnName = 'IdentityValue' AND @OrderAscending  = 0 THEN rnDesc END,
   CASE WHEN @OrderByColumnName = 'IdentityValue' AND @OrderAscending  = 1 THEN rnDesc END
于 2011-12-13T14:50:46.583 に答える