How To:Ghost Record を確認する方法

Ghost Record とは?

SQL Server の Books Onlineでは、以下のように説明があるものです。

実体レコード (ghost record)
削除対象として指定されているものの、まだデータベース エンジンによって削除されていない、インデックスのリーフ レベルの行。

簡単に書くと、DELETE したけど、まだ実際には削除されていないレコードのことです。SQL Server はDELETEを実行する際に、パフォーマンスの観点から、対象レコードに「削除した」というマークだけを付けています。実際にこのマークされたレコードは、「Ghost Cleanup Task」という処理が削除してくれて、初めてその削除されたレコードが使っていた領域が、再利用可能になるという、そんな感じの仕組みです。なお、インデックスとありますが、Heap(クラスタ化インデックスがないテーブル)でもGhost Recordは発生します。

今回のポストは、このGhost Recordを確認する方法をご紹介します。

「何故確認方法が必要なのか?」といいますと、このGhost Recordが「Ghost Cleanup Task」によってCleanupされないという状況が発生する場合があるためです。この状況になっていると、レコードは全然ないのに圧縮できないといった状態になります。もし、「レコード件数は少ないのに、妙にテーブルのサイズが大きい」とか「レコード削除したはずなのに、データベースが思ったように圧縮されない」という現象を経験したら、Ghost Recordが大量に溜まっていないか、一度確認してみてください。

確認方法:SQL Server 2005/2008/2008 R2

sys.dm_db_index_physical_stats 動的管理関数を使用することで、確認が可能です。例えば、対象のデータベースで下記のように実行すれば、ghost_record_count が存在しているテーブルを確認することができます。

select object_name(object_id) as [Name],ghost_record_count,* from sys.dm_db_index_physical_stats(DB_ID(),NULL,NULL,NULL,'DETAILED') where ghost_record_count>0

確認方法:SQL Server 2000

残念ながら公開されている確認方法はありません。

対処方法

対象のインデックスを再構築することで、大量に溜まったGhost Recordを消し去ることが可能です。

Heapの場合、一旦クラスタ化インデックスを作成し、削除することで対処可能です(断片化解消と同じ方法です)。