私は最近、1つのヒープテーブルに70%以上の断片化があることがわかりました。だから私はすることにしました
ALTER TABLE dbo.myTable REBUILD
面白いことに、その後20%の断片化がありました。それ以来、そのテーブルへの書き込みはありませんでした。だから私はもう一度リビルドをすることにしました。
2回目以降は、テーブルハットの断片化が50%増えるため、さらに多くのことを実現できます。 どうしてこんなことが起こるのか本当にわかりません...
私は最近、1つのヒープテーブルに70%以上の断片化があることがわかりました。だから私はすることにしました
ALTER TABLE dbo.myTable REBUILD
面白いことに、その後20%の断片化がありました。それ以来、そのテーブルへの書き込みはありませんでした。だから私はもう一度リビルドをすることにしました。
2回目以降は、テーブルハットの断片化が50%増えるため、さらに多くのことを実現できます。 どうしてこんなことが起こるのか本当にわかりません...
回答:
ヒープ内での断片化の意味
DMV avg_fragmentation_in_percent
をクエリして列から取得するヒープの断片化値sys.dm_db_index_physical_stats
は、
インデックスの論理断片化、またはIN_ROW_DATAアロケーションユニットのヒープのエクステント断片化。
さらに、同じBOLは、
これは、ヒープのリーフページ内の順不同のエクステントの割合です。順不同エクステントとは、ヒープの現在のページを含むエクステントが、前のページを含むエクステントの次のエクステントと物理的に異なるエクステントです。
あなたはそれが見ることができるようにヒープに割り当てられたページ内の空き領域の存在ではないが、ページの様々な一連の断片化を作成します。
これは小さなテストで実証できます。ヒープテーブルを作成し、レコードをいくつか挿入してから、断片化をチェックします。
create table dbo.HeapTest
(
Id INT not NULL Default (1),
Col1 char(5000) Not null Default ('Heaps Are Cool')
)
SET NOCOUNT ON
Insert into dbo.Heaptest default values
go 50
select index_type_desc,avg_fragmentation_in_percent,fragment_count,
avg_page_space_used_in_percent,record_count
from sys.dm_db_index_physical_stats(db_id(),object_id('dbo.HeapTest','U'),0,default,'detailed')
したがって、ヒープテーブルは50レコードで作成されます。以下は、クエリDMV sys.dm_db_index_physical statsの後の断片化の様子です。
avg_fragmentation_in_percent
列の値が33%であることがわかります。次に、ページがどのように配置されているかを見てみましょう。これは、文書化されていないクエリを使用して行うことができます%%lockres%%
。クエリは
SELECT %%lockres%%, * FROM dbo.HeapTest;
そして、出力は次のようになります。該当する部分のみを添付します。dbo.HeapTestテーブルに50行を挿入したため、クエリは50行を生成しました。
最初のページにはIDがあり197
、次のページにはIDがあります。242
後続のページには、ページIDに到達するまで継続的なID 264
があります280
。したがって、ページID番号のこのジャンプが、実際に断片化を引き起こしています。
次に、ヒープを再構築してコマンドを再度実行して、断片化とページの配置を確認します。次のような断片化が発生します
断片化が今であることがわかります14%
。
割り当てられたページ番号を見てみましょう
ジャンプレストは1つだけで、すべてのページにシリアルにページIDが割り当てられます。ジャンプが1つしかないため、断片化が大幅に減少しました。
ヒープを再構築しましたが、断片化をチェックすると完全になくなりました。そしてページIDの割り当ては
断片化が増加した理由
これで、断片化が発生する原因について確認できます。ページがヒープに割り当てられているとき、ページが連続的ではないことを裏付けることができます。上記のように、断片化の値が増加する原因は、ページに割り当てられているPAGE IDのジャンプでした。
頭の後ろで、HEAPのフラグメント化という言葉には意味がないことにも注意してください。順序付けされていない一連のページのフラグメント化をどのように定義しますか。
断片化が本当に心配
ヒープテーブルが断片化し、クエリが遅くなるシナリオに本当に直面している場合は、テーブルを再構築するよりもテーブルにクラスター化インデックスを作成する方が適切です。理由は、ヒープを再構築すると、基になる非クラスター化インデックスもすべて再構築されるため、再構築プロセスに非常に長い時間がかかり、多くのリソースを利用し、トランザクションログが膨らむためです。本番システムでは、常にこれを回避しようとします。パウロはこれについて、ヒープに関する神話のセクションで取り上げました。
PS:本番システムでは、文書化されていないコマンドを使用しないでください。これはデモ用です。
Heaptest
、結果を探して提供します。きっと何かを見逃しているかもしれません。その場合、互換性レベルが80でないことを確認して