並列処理(パーティションストリーム)演算子が行の推定値を1に減らすのはなぜですか?


12

SQL Server 2012 Enterpriseを使用しています。私は完全に直感的ではないいくつかの動作を示しているSQLプランに出会いました。大量のパラレルインデックススキャン操作の後、パラレル化(パーティションストリーム)操作が発生しますが、インデックススキャン(Object10.Index2)によって返される行の推定値を強制終了し、推定値を1に減らします。この振る舞いを説明するものに出会ったことはありません。クエリは非常に単純ですが、各テーブルには数百万のレコードが含まれています。これはDWHロードプロセスの一部であり、この中間データセットは何度も触れられますが、私が抱えている問題は、特に行の見積もりに関連しています。正確な行の推定値が並列処理(パーティション分割)演算子内で1になる理由を説明できますか?また、

計画を貼り付けるために完全な計画を投稿しました

問題の操作は次のとおりです。

ここに画像の説明を入力してください

コンテキストを追加する場合に備えてプランツリーを含める:

ここに画像の説明を入力してください

Paul Whiteが提出したこのConnectアイテムのバリエーションにぶつかることはありますか(彼のブログさらに詳しく説明しています)。少なくとも、私が見つけた唯一のものは、プレイ中のTOP演算子がなくても、私が実行しているものに少しでも近いようです。

回答:


9

ビットマップフィルターを使用したクエリプランは、読みにくい場合があります。以下からの再分割ストリームのBOLの記事(強調鉱山):

Repartition Streamsオペレーターは、複数のストリームを消費し、レコードの複数のストリームを生成します。レコードの内容と形式は変更されません。クエリオプティマイザーがビットマップフィルターを使用する場合、出力ストリームの行数が削減されます。

さらに、ビットマップフィルターに関する記事も役立ちます。

ビットマップフィルタリングを含む実行プランを分析する場合、データがプランをどのように流れ、フィルタリングが適用されるかを理解することが重要です。ビットマップフィルターと最適化されたビットマップは、ハッシュ結合のビルド入力(ディメンションテーブル)側に作成されます。ただし、実際のフィルタリングは通常、ハッシュ結合のプローブ入力(ファクトテーブル)側にある並列処理演算子内で実行されます。ただし、ビットマップフィルターが整数列に基づいている場合、フィルターは並列処理演算子ではなく、初期テーブルまたはインデックススキャン操作に直接適用できます。この手法は、行内最適化と呼ばれます。

私はそれがあなたのクエリで観察していることだと信じています。ビットマップ演算子がIN_ROWファクトテーブルに反している場合でも、再パーティションストリーム演算子がカーディナリティの推定値を削減することを示す比較的単純なデモを思いつくことができます。データ準備:

create table outer_tbl (ID BIGINT NOT NULL);

INSERT INTO outer_tbl WITH (TABLOCK)
SELECT TOP (1000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values;

create table inner_tbl_1 (ID BIGINT NULL);
create table inner_tbl_2 (ID BIGINT NULL);

INSERT INTO inner_tbl_1 WITH (TABLOCK)
SELECT (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) / 2000000 - 2) NUM
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;

INSERT INTO inner_tbl_2 WITH (TABLOCK)
SELECT (ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) / 2000000 - 2) NUM
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;

実行すべきではないクエリを次に示します。

SELECT *
FROM outer_tbl o
INNER JOIN inner_tbl_1 i ON o.ID = i.ID
INNER JOIN inner_tbl_2 i2 ON o.ID = i2.ID
OPTION (HASH JOIN, QUERYTRACEON 9481, QUERYTRACEON 8649);

計画をアップロードしました。近くのオペレーターを見てくださいinner_tbl_2

行を失った再パーティション

また、Paul WhiteによるNullable Columnsのハッシュ結合の 2番目のテストが役立つ場合があります。

行削減の適用方法にはいくつかの矛盾があります。少なくとも3つのテーブルがある計画でしか見ることができませんでした。ただし、適切なデータ分散を使用すると、予想される行の削減は合理的と思われます。ファクトテーブルの結合された列に、ディメンションテーブルに存在しない繰り返し値が多数あるとします。ビットマップフィルターは、結合に到達する前にそれらの行を削除する場合があります。クエリの場合、推定値は1までずっと削減されます。ハッシュ関数間で行がどのように分散されるかが良いヒントになります。

行ディストリビューション

それに基づいて、Object1.Column21列に繰り返し値がたくさんあると思われます。繰り返し列がたまたま統計のヒストグラムにない場合Object4.Column19 SQL Serverはカーディナリティの推定値を非常に間違っている可能性があります。

クエリのパフォーマンスを改善できる可能性があるので、心配する必要があると思います。もちろん、クエリが応答時間またはSLA要件を満たしている場合は、さらに調査する価値はありません。ただし、さらに調査したい場合は、(統計の更新以外に)クエリオプティマイザーがより良い情報を持っている場合に、より良い計画を選択するかどうかを知るためにできることがいくつかあります。あなたは結果が間の結合入れることができますDatabase1.Schema1.Object10し、Database1.Schema1.Object11一時テーブルに、あなたは、ネストされたループ結合を取得し続けるかどうかを確認します。LEFT OUTER JOINクエリオプティマイザーがそのステップで行数を削減しないように、その結合を変更できます。MAXDOP 1クエリにヒントを追加して、何が起こるかを確認できます。使用できますTOP派生テーブルを使用して、結合を最後に強制するか、クエリから結合をコメントアウトすることもできます。うまくいけば、これらの提案はあなたが始めるのに十分です。

質問の接続項目に関して、それがあなたの質問に関連していることはほとんどありません。その問題は、貧弱な行の見積もりとは関係ありません。これは、バックグラウンドでクエリプランで処理される行が多すぎる原因となる並列処理の競合状態に関係しています。ここでは、クエリが余分な作業を行っていないようです。


6

ここでの中心的な問題は、最初の結合の結果に対するカーディナリティの推定値が低いことです。これは多くの理由で発生する可能性がありますが、ほとんどの場合、古くなった統計または多数の相関結合述語のいずれかであり、オプティマイザーのデフォルトモデルは独立していると想定しています。

後者の場合、FIX:SQL Server 2008またはSQL Server 2008 R2またはSQL Server 2012で相関AND述語を含むクエリを実行すると、サポートされているトレースフラグ4137を使用してパフォーマンスが低下する可能性があります。オプティマイザーの修正を有効にするトレースフラグ4199、および/またはモデリング拡張機能を有効にする2301。匿名化された計画に基づいて知ることは困難です。

ビットマップの存在は、結合のカーディナリティ推定に直接影響しませんが、早期の半結合削減を適用することにより、その効果をより早く見えるようにします。ビットマップがなければ、最初の結合のカーディナリティの推定値は同じになり、計画の残りの部分はそれに従って最適化されます。

興味がある場合は、テストシステムで、トレースフラグ7498を使用してクエリのビットマップを無効にできます。最適化後のビットマップ(オプティマイザによって考慮され、カーディナリティの推定値に影響します)を無効にして、最適化後のビットマップに置き換えます(考慮されません)トレースフラグ7497と7498の組み合わせによるオプティマイザによるカーディナリティへの影響はありません。どちらも実稼働システムでの使用については文書化もサポートもされていませんが、オプティマイザが通常検討できる計画を作成するため、計画ガイド。

上記の最初の結合の貧弱な見積りの核となる問題をこれで解決することはないので、私は本当にそれを興味のために言及しているだけです。

ビットマップとハッシュ結合の詳細:


0

Twitterであなたに返信しました。添付のXMLを見て、不均衡な並列処理が見られます。1つのスレッドには実際の行のほとんどすべてがありますが、他のほとんどにはありません。不均衡な並列処理が叫ばれています。したがって、キー/結合値と、それぞれの統計とカーディナリティを調べます。

あなたの他の考えでは、あなたが貼り付けた計画には私が見たどこにもTOPが含まれていないので、私はConnectアイテムが適用されるかどうかは確かではありません。

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