ORDER BYが2つのテーブルをEXCEPTの前(遅い)にソートし、後(速い)にソートしないのはなぜですか?


12

SQL Server 2008 R2クエリオプティマイザーパズル

2つのテーブルがあり、どちらにも900万行が含まれています。70.000行は異なり、他は同じです。

これは高速、13秒です。

select * from bigtable1
except select * from similar_bigtable2

これにより出力がソートされ、13秒も高速になります。

select * into #q from bigtable1
except select * from similar_bigtable2
select * from #q order by sort_column

これは非常に遅いですが、

;with q as (
    select * from bigtable1
    except select * from similar_bigtable2
)
select * from q order by sort_column

そして、クエリの特定の部分を事前に計算する必要があることをSQL Serverに示唆するために時々使用する「トリック」でさえ、機能せず、クエリが遅くなります。

;with q as (
    select top 100 percent * from bigtable1
    except select * from similar_bigtable2
)
select * from q order by sort_column

クエリプランを見ると、理由を見つけるのは難しくありません。

クエリプラン ORDER BYを使用したクエリプラン

SQL Server は、ハッシュ一致の前に 2種類の900万行を配置します、ハッシュ一致の後に 1種類の70.000行のみを追加することをお勧めします。

質問:クエリオプティマイザーにそのように指示するにはどうすればよいですか?


3
ハッシュマッチの前にソートするのではなく、ソートしてからマージ結合(ハッシュ結合ではない)を実行します。ハッシュ結合を強制する(またはマージ結合を防止する)ヒントがありますか?
ティロ

3
SQL Serverクエリオプティマイザーは、データの並べ替えが有益であると判断したため、非常に遅いハッシュ一致結合またはネストされたループ結合ではなく、はるかに高速なマージ結合(並べ替えられたデータに対してのみ機能します)を使用できるようになったようです....
marc_s

9
EXCEPT(例OUTER JOIN)に代わるものを試しましたか?構文はあまり便利ではありませんが、そこでインデックス/結合のヒントをよりうまく使用できる場合があります(または必要がない場合もあります)。現在使用している代替手段(#tempテーブルに最初に入れるもの)は最後の回避策ですが、場合によっては、オプティマイザーに希望する方法でクエリの2つの部分を完全に分離させる唯一の方法です。
アーロンバートランド

回答:


1

これら2つのクエリプランの主な違いは、実際にはハッシュマッチとマージ結合の違いです。ハッシュマッチはより効率的であり、クエリ1はオプション1(CTEを使用しない)でより高速に実行されることがわかります。

CTEは優れたツールですが、複雑な述語または非一意の親/子キーの2つの場合には効率的ではないようです。あなたの場合、一意のキーはなく、SQLサーバーは要件を満たすために最初にデータセットをソートする必要があります。この問題の詳細については、以下のリンクをご覧ください:http : //blogs.msdn.com/b/sqlcat/archive/2011/04/28/optimize-recursive-cte-query.aspx

そのため、その速度の遅さを受け入れるか、より効率的なWHILEループでロジックを書き換える必要があるようです。


0

これを試してみてください。

select * from
(
    select * from bigtable1
    except 
    select * from similar_bigtable2
) t
order by sort_column

0

これは理想的なソリューションではありませんが、tsqlを構造化して効率的なプランを生成できない場合は、プランガイドを設定して必要なプランを強制することができます。これを行うと、より効率的な計画が利用可能になった場合、SQLはそれを考慮しませんが、それはオプションです。

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