以前にゆっくり実行されていたクエリがあります。後で私はそれが並列に実行されておらず、これがクエリの実行を遅くしていることがわかりました。
クエリには、大きなview
が含まれ、大量のtemp tables
およびsub query
を使用してビューをクエリします。
ビューからUDF
を1つ削除してinline functions
を使用し、スカラーTVF
も使用したところ、parallel execution
で高速に実行されました。
数日間は順調でしたが、ある晴れた日、クエリの実行が遅いことに気付きました。実行プランを確認したところ、クエリがシリアルモードで実行されていることがわかりました。クエリのプランキャッシュを確認したところ、そのビューに関連するキャッシュされたプランがたくさんありました。並列でないプランを削除したところ、クエリがすばやく実行されました。
これを毎朝実行して、クエリを強制的に並列実行します。
さらなる詳細:
クエリを強制的に永久に並列実行するにはどうすればよいですか?
一見、これは古典的な パラメータスニッフィング 問題のように聞こえます。
SQL Serverは、計画をコンパイルする必要があるときに呼び出される最初のパラメーターセットの実行計画を作成し、その計画を1日を通して繰り返し再利用します。それらがどのようなパラメーターであるかを確認できます。シリアルプランを表示しているときに、selectステートメントを右クリックして、プロパティに移動します。プロパティウィンドウで、[パラメーター]を探し、次に[コンパイルされた値]を探します。これにより、シリアルプランを生成する値が表示されます。
計画を常に並行して実行するように強制するには、次のようないくつかの異なるオプションがあります(その多くは、Erlandが彼の優れた投稿で取り上げています)。
それは簡単な答えです-しかし、はるかに多くのことを読んでください Erlandの優れた投稿、アプリで遅い、SSMSで速い 1つのクエリが異なるプランを取得する方法とそれを修正する方法を説明しています。
クエリがどのように見えるかわからないため、問題に対する正確な回答を提供するのは難しいかもしれませんが、SQL 2016で導入されたQueryStore機能を使用して特定のプランを強制できます。以前のバージョンのSQL Serverまたはクエリストアがソリューションであるとは思わない-次のようなことを試してみてください。
このトピックに関するStackExchangeの以前の投稿も確認する必要があります。 SQLが非常に大きなクエリの並列処理を行わない
クエリのコストがCost Threshold of Parallelism
の値を超え、cost of the parallel plan
がcost of a serial plan
より小さい場合、並列プランが作成されて使用されます。
場合によっては、parallel plan
はserial plan
よりも高価であるため、QOは並列プランよりもシリアルプランを選択します。たとえば、クエリに並列モードで実行できないスカラーまたは関係演算子が含まれている場合。
場合によっては、不正確な情報、古い統計、貧弱なcardinality estimate
などが原因で、QOが誤った判断を下します。シリアルプランのコストがparallel plan
よりわずかに高いためです。
したがって、QOは引き続きシリアルプランを選択します。
この問題を克服するには、クエリを最適化し、統計も更新する必要があります。
これは、QOが正しい決定を行うのに役立ちます。
ビューから1つのUDFを削除し、インライン関数を使用し、スカラーTVFも使用しました
これらは歓迎すべきステップです。クエリを改善するとすぐに、一部のプランは並列になり、クエリのパフォーマンスが改善されました。
したがって、クエリを改善する余地があるかもしれません。
Hint
をすぐに試すよりも、クエリの最適化とインデックスの調整にもっと注意を払う必要があります
HINT、パラメータスニッフィング、OPTION(RECOMPILE)の使用などの残りの部分については、すでに説明しています。