Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
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の場合、一旦クラスタ化インデックスを作成し、削除することで対処可能です(断片化解消と同じ方法です)。