web-dev-qa-db-ja.com

ハッシュ集約救済

チャットディスカッションで生じた質問:

私は知っていますハッシュ結合救済は入れ子になったループの一種に内部的に切り替わります。

SQL Serverはハッシュ集計救済(それが発生する可能性がある場合)に対して何をしますか?

10
Paul White 9

Hash joinhash aggregateはどちらも同じ演算子コードを内部で使用しますが、ハッシュ集約は単一の(ビルド)入力のみを使用します。 ハッシュ集約の基本的な操作は Craig Freedmanによって記述されています

ハッシュ結合と同様に、ハッシュ集計にはメモリが必要です。 SQL Serverは、ハッシュ集計を使用してクエリを実行する前に、基数の見積もりを使用して、クエリを実行するために必要なメモリの量を見積もります。ハッシュ結合では、各ビルド行を保存するため、合計メモリ要件はビルド行の数とサイズに比例します。結合する行数と結合の出力カーディナリティは、結合のメモリ要件に影響を与えません。ハッシュ集約では、グループごとに1行を格納するため、合計メモリ要件は実際には出力グループまたは行の数とサイズに比例します。列ごとのグループの一意の値とグループが少ない場合、必要なメモリは少なくなります。列ごとのグループの一意の値とグループが多い場合は、より多くのメモリが必要です。

彼はさらにハッシュ再帰について話します:

では、メモリが不足するとどうなりますか?繰り返しになりますが、ハッシュ結合と同様に、メモリが不足した場合は、tempdbに行を書き出す必要があります。 1つ以上のバケットまたはパーティションをスピルし、部分的に集計された結果と、スピルしたバケットまたはパーティションにハッシュする新しい行を追加します。あふれた新しい行を集約しようとはしていませんが、ハッシュしてそれらをいくつかのバケットまたはパーティションに分割します。すべての入力グループの処理が完了したら、完成したメモリ内グループを出力し、こぼれたパーティションを一度に1つずつ読み取って集計することにより、アルゴリズムを繰り返します。こぼれた行を複数のパーティションに分割することにより、各パーティションのサイズを小さくし、アルゴリズムが何度も繰り返す必要があるリスクを減らします。

救済

Hash bailoutは簡単に文書化されていますが、Nacho Alonso Portilloによって 救済を強制する前のハッシュイテレータの再帰の最大レベルはいくつですか?

値は定数で、製品にハードコードされており、その値は5です。これは、ハッシュスキャンオペレーターが、ワークスペースからの許可されたメモリに収まらない特定のサブパーティションのソートベースのアルゴリズムに頼る前に、元のパーティションをより小さなパーティションに分割する前の5回の試行が行われている必要があることを意味します。

そこに言及されている「ハッシュスキャン演算子」は、内部クラスCQScanHashへの参照がsqlmin.dll。このクラスは、実行計画で見られるハッシュ演算子(部分的な集計やフローの区別を含むすべての形式)の実装の先頭に立っています。

救済アルゴリズム

これは私たちをあなたの質問の核心に導きます-救済アルゴリズムは正確に何をしますか?それは「ソートベース」ですか、それとも「一種の入れ子ループ」に基づいていますか?

あなたの視点にもよるが、間違いなく両方だ。ハッシュの再帰がレベル5に達すると、メモリ内のハッシュパーティションは、ハッシュテーブルから、ハッシュ値の最初は空のbツリーインデックスに変わります。以前に流出した単一のハッシュパーティションからの各行は、Bツリーインデックスで検索され、必要に応じて挿入(新しいグループ)または更新(集約の維持)されます。

Bツリーへのこの一連の順序付けられていない挿入は、同様に 挿入ソート またはインデックス付きのネストされたループのルックアップとして見ることができます。

いずれにしても、このフォールバックアルゴリズムは、メモリを割り当てずに最終的に完了することが保証されています。 bツリーに使用可能なスペースがオーバーフローパーティションからのすべてのグループ化キーと集約を保持するのに十分でない場合は、複数のパスが必要になる場合があります。

Bツリーインデックスを保持するために利用可能なメモリが使い果たされると、(現在のスピルパーティションからの)それ以上の行が単一の新しいtempdbパーティションに送信されます(これは保証されています)小さい)、プロセスは必要に応じて繰り返されます。ハッシュrecursionが終了したため、流出レベルは5のままです。いくつかの処理の詳細は、文書化されていないトレースフラグ7357で確認できます。

11
Paul White 9