以下は、Microsoft Docsの段落です。
DML操作の一部としてヒープに割り当てられた新しいページは、ヒープが再構築されるまでPAGE圧縮を使用しません。圧縮を削除して再適用するか、クラスター化インデックスを作成および削除して、ヒープを再構築します。
なぜそうなのか分かりません。圧縮設定が指定されたヒープがある場合、テーブルに属するページに適用されないのはなぜですか?
ありがとう
以下は、Microsoft Docsの段落です。
DML操作の一部としてヒープに割り当てられた新しいページは、ヒープが再構築されるまでPAGE圧縮を使用しません。圧縮を削除して再適用するか、クラスター化インデックスを作成および削除して、ヒープを再構築します。
なぜそうなのか分かりません。圧縮設定が指定されたヒープがある場合、テーブルに属するページに適用されないのはなぜですか?
ありがとう
回答:
違いの原因となる特定の内部メカニズムはわかりませんが、ヒープはクラスター化インデックス(および場合によっては非クラスター化インデックス)とはわずかに異なる方法で(内部的に)管理されていると言えます。
1つ以上のデータページが空である(割り当てられた行がない)ようにヒープから行を削除しても、必ずしもそのスペースが解放されるわけではありません。テーブルにクラスター化インデックスを作成してから削除するか、呼び出す必要がありますALTER TABLE [TableName] REBUILD;
(SQL Server 2014以降)。詳細とオプションについては、DELETEの Microsoft Docsページを参照してください。
個々の行(つまり、セットベースでINSERT
はない)をヒープに挿入しても、クラスター化インデックスの場合ほどデータページがいっぱいになりません。クラスター化インデックスは、行(データおよび行オーバーヘッド)のスペースとスロット配列の2バイトのオーバーヘッドがある限り、行に適合します。ただし、ヒープ内のデータページは、ページに残っているバイト数を使用せず、代わりにページがどれだけいっぱいかを示す非常に一般化されたインジケーターを使用し、報告されるレベルはそれほど多くありません。レベルは、0%、20%、50%、80%、および100%フルのラインに沿ったものです。そして、別の行のためのスペースがまだある間に100%に切り替わります(実際、同じ数の行がセットベースの操作で挿入されていれば、可能な限りページを埋めていました)。もちろん、DELETE
操作、ヒープの再構築では、データページに収まるだけの行がパックされます。
ここで、ページ圧縮の実装に関するMicrosoft Docsページの「ページ圧縮が発生するとき」セクションから取得した以下の情報を検討します。
...データが最初のデータページに追加されると、データは行圧縮されます。...ページがいっぱいになると、追加される次の行がページ圧縮操作を開始します。ページ全体がレビューされます。...
したがって、データページが書き込まれる前に、ALTER TABLE REBUILD、クラスター化インデックスの作成/削除、またはデータ圧縮設定(すべてがヒープを再構築)の変更を必要とすることは、この他のヒープ動作と完全に一致しているようです。最適。ヒープが「ページ全体」を完全に認識しておらず(ヒープが再構築されるまで)、ページが完全にいっぱいになったことがわからない場合、ページ圧縮操作をいつ開始するか(更新とシングルを処理するとき)行挿入)。
ページ圧縮の自動適用からヒープをさらに制限するもう1つの技術的特徴は(そうでない場合でも)、圧縮を適用すると、そのヒープ(存在する場合)のすべての非クラスター化インデックスを再構築する必要があることです。「データ圧縮」のリンクページにも次のように記載されています。
ヒープの圧縮設定を変更するには、テーブルのすべての非クラスター化インデックスを再構築して、ヒープ内の新しい行の場所へのポインターを持たせる必要があります。
参照される「ポインター」は行ID(RID)であり、ファイルID、ページID、およびページ上のスロット/位置の組み合わせです。これらのRIDは非クラスター化インデックスにコピーされます。正確な物理的な場所であるため、クラスター化インデックスキーを使用してbツリーを走査するよりも、検索が高速になる場合があります。しかし、物理的な場所の1つの欠点は、場所が変わる可能性があることであり、それがここでの問題です。ただし、クラスター化インデックスは、キー値がクラスター化インデックスへのポインターとして非クラスター化インデックスにコピーされるため、この問題の影響を受けません。キーの値は、物理的な場所が変わっても同じままです。
参照:
ヒープ(クラスター化インデックスのないテーブル)のMicrosoft Docsページの「ヒープの管理」セクション:
ヒープを再構築して無駄なスペースを取り戻すには、ヒープ上にクラスター化インデックスを作成し、そのクラスター化インデックスを削除します。
データ圧縮に関するMicrosoft Docsページの「行とページの圧縮を使用する場合の考慮事項」セクション:
ヒープがページレベルの圧縮用に構成されている場合、ページは次の方法でのみページレベルの圧縮を受け取ります。
- データは一括最適化を有効にして一括インポートされます。
- INSERT INTO ... WITH(TABLOCK)構文を使用してデータが挿入され、テーブルに非クラスター化インデックスがありません。
- PAGE圧縮オプションを指定してALTER TABLE ... REBUILDステートメントを実行すると、テーブルが再構築されます。
そして質問で引用された声明。
SQL Serverのすべてのメカニズムが、そうあるべきだと信じているわけではありません。
Paul Randalは、問題の管理に関する強力な推奨事項を提供しています。
http://www.sqlskills.com/blogs/paul/a-sql-server-dba-myth-a-day-2930-fixing-heap-fragmentation/