41

ステートメントを多用するストアド プロシージャを含む ETL プロセスがありSELECT INTOます (最小限にログに記録されるため、生成されるログ トラフィックが少なくなるため高速になります)。1 つの特定のストアド プロシージャで行われる作業のバッチのうち、最もコストのかかる操作のいくつかは、クエリ結果をバッファリングし、作成中のテーブルにコピーするように見える熱心なスプールです。

熱心なスプールに関する MSDN ドキュメントは非常にまばらです。これらが本当に必要かどうか (そしてどのような状況で) について、より深い洞察を持っている人はいますか? 理にかなっているかもしれないし、そうでないかもしれないいくつかの理論がありますが、クエリからこれらを排除することに成功していません.

.sqlplan ファイルは非常に大きい (160kb) ため、フォーラムに直接投稿するのはおそらく妥当ではないと思います。

したがって、特定の回答に適している可能性のあるいくつかの理論を次に示します。

  • クエリは、フォーマットされた日付の解析など、データ変換のためにいくつかの UDF を使用します。このデータ変換では、テーブルを構築する前に適切な型 (varchar の長さなど) をテーブルに割り当てるために熱心なスプールを使用する必要がありますか?
  • 上記の質問の延長として、クエリでこの操作を駆動するものと駆動しないものについて、より深い見解を持っている人はいますか?
4

1 に答える 1

34

スプーリングについての私の理解は、それがあなたの実行計画のちょっとしたニシンだということです。はい、クエリコストの多くを占めていますが、実際にはSQL Serverが自動的に実行する最適化であり、コストのかかる再スキャンを回避できます。スプーリングを回避すると、それが存在する実行ツリーのコストが上昇し、ほぼ確実にクエリ全体のコストが増加します。特にSQLコードを見ずに、データベースのクエリオプティマイザがそのように実行を解析する原因については特に洞察がありませんが、その動作を信頼する方がよいでしょう。

ただし、これは、実行計画が最適化できないことを意味するわけではありません。これは、現在の状況やソースデータの揮発性によって異なります。を実行しているときSELECT INTO、実行プランにスプーリングアイテムが表示されることがよくあり、これは読み取りの分離に関連している可能性があります。特定の状況に適している場合は、トランザクション分離レベルをより安価なものに下げるか、NOLOCKヒントを使用してみてください。複雑なパフォーマンスクリティカルなクエリでNOLOCK、データに安全で適切であれば、理由がないように見えても、クエリの実行速度を大幅に向上させることができることがわかりました。

この状況で、READ UNCOMMITTEDまたはNOLOCKヒントを試してみると、一部のスプールを削除できる場合があります。(明らかに、一貫性のない状態になる可能性がある場合は、これを実行したくありませんが、データ分離の要件は人によって異なります)。TOPオペレーターとオペレーターがスプーリングを引き起こすことがありますが、ETLプロセスでこれらのORいずれかを実行しているとは思えません...

あなたのUDFも犯人である可能性があると言っているのは正しいです。各UDFを1回だけ使用する場合は、UDFをインラインに配置して、パフォーマンスが大幅に向上するかどうかを確認することをお勧めします。(そして、クエリとインラインでそれらを書き込む方法がわからない場合は、おそらくそれがスプーリングを引き起こしている可能性があります)。

最後に、並べ替え可能な結合を実行している場合は、ヒントを使用して、最も選択的な順序であることがわかっている順序で結合順序を強制的に実行してみてください。それは少し手が届きますが、すでに最適化に行き詰まっている場合は、試してみても問題ありません。

于 2008-09-17T20:23:10.133 に答える