枝刈りと非断片化のタイミング

枝刈りと非断片化は常に行われるわけではない。以下がの2つの条件が成立したときに枝刈りと非断片化が行われる。

  1. ブロック内の空き領域が、FILLFACTORで設定した値か、ブロックサイズの1/10(約800バイト)を下回っている。あるいは空き領域不足のために直近のUPDATEが、同じブロック内に行を獲得することに失敗した
  2. 枝刈りが可能であることを示すフラグが該当ブロックに立っている

1から、HOTを活用するためには、FILLFACTORの設定が重要であることがわかる。

2のフラグは、UPDATE、DELETEが成功(コミット)したときに立つ。

UPDATE、INSERTしたトランザクションがアボートした際には、枝刈りと非断片化が行われないので、VACUUMが必要になる。

なお、枝刈りと非断片化のタイミングに関しては、ヒューリスティックに頼っている部分があるため、今後のバージョンでは変更される可能性がある。

HOTの制限事項

残念ながら、HOTはすべてのケースに適用できるわけではない。以下のような条件が必要だ。

  • 更新処理において、更新対象(値が変化する)列にインデックスが張られていないこと。たとえば先の例で言えば、cnt列の更新はHOTの適用対象になるが、url列にはインデックスがはってあるので、HOTは適用されない。
  • 更新対象の行が含まれるブロックに空き領域があること。たとえば、空の状態のテーブルにINSERTやCOPYでびっしりと行を追加してしまうとHOTは適用されなくなる。これを防ぐには、CREATE TABLE時にFILLFACTORを適切に指定する。

このほか、更新後の行がスペース的に同じブロックに入らず、他のブロックに格納された場合もHOTは適用されないが、これはあまり頻繁に起きるようなことではないと思われる。

HOTの使いこなし

HOTによって、今までPostgreSQLの適用が困難だった、更新が頻繁で、かつテーブルサイズが大きいデータベースにも、PostgreSQLの適用範囲を広げることができるようになった。

ただし、HOTを使いこなすためには、不必要なインデックスを作らないとか、FILLFACTORを適切に設定すると言った配慮が必要になる。このあたりは、データベース設計者の腕の見せどころであろう。