SQL ServerがCTEを「最適化フェンス」として使用する場合に決定するルールは何ですか?


10

しばらく前に、Brent OzarがSQL ServerとPostgreSQLの違いのいくつかを詳しく説明した投稿を公開しました:

SQL ServerとPostgreSQLの2つの重要な違い

最初のポイント(「CTEは最適化フェンス」)が私の目を引きました。提供されている例では、SQL ServerがCTEとメインクエリを組み合わせ、それを単一のクエリとして最適化している( PostgreSQL)。

ただし、この動作は、SQL ServerがCTEを最適化フェンスとして扱う他のブログやトレーニングクラスで見た例とは逆のようです。これにより、インデックスの使用やパフォーマンスの向上などが可能になります。次に例を示します。

星を選択するより良い方法

したがって、SQL ServerはCTEを最適化のフェンスとして「称賛」しているようです。SQL ServerがCTEを最適化フェンスとして確実に尊重する既知のケース(またはその逆の動作)の特定のリストを文書化する優れたリソースはありますか?

回答:


10

... SQL ServerがCTEを最適化フェンスとして確実に尊重する既知のケースのリスト

そのようなリストは、信頼性を保証することなく、観察された動作に依存します。

SQL Serverクエリオプティマイザーは、一般的なテーブル式をそれ自体最適化フェンスとして処理することはありませんが、全体にわたって最適化することが明らかに難しい構成もあります。再帰CTEはこの良い例です。

CTEは、ビュー/インライン関数/サブクエリ/派生テーブルと非常によく似ており、クエリにインライン化されます。観察された「フェンス」の動作は、オプティマイザが原理内の透過境界を越えて最適化できないか、最適化できないと判断するかによって異なります。

一般的に言えば、CTEがよりシンプルで「リレーショナル」であるほど、オプティマイザがビットを移動できる可能性が高くなります。

オプティマイザがCTEの「結果」を考慮したり強制したりできるようにする機能が提案されていますが、まだ実装されていません。

それまでの間、最も一般的な回避策は、一時テーブルまたはテーブル変数で中間結果セットを明示的に具体化することです。これには明らかに、単一のステートメントに限定されないシナリオが必要です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.