高い同時実行性を可能にするために、PostgreSQLはマルチバージョン同時実行制御(MVCC)を使用して行を格納します。 しかし、MVCCには更新クエリに対していくつかの欠点があります。 特に、更新では、テーブルに新しいバージョンの行を追加する必要があります。 また、更新された行ごとに新しいインデックスエントリが必要になる可能性があり、古いバージョンの行とそのインデックスエントリを削除するとコストが高くなります。
更新のオーバーヘッドを減らすために、PostgreSQLにはヒープ専用タプルHOTと呼ばれる最適化があります。 この最適化は以下の場合に可能です。
更新は、式や部分インデックスを含むテーブルのインデックスによって参照されるカラムを変更しません。
古い行を含むページには、更新された行に対して十分な空き領域があります。
そのような場合に、ヒープ専用タプルは2つの最適化を提供します。
更新された行を表すために新しいインデックスエントリは必要ありません。
更新された行の古いバージョンは、定期的なバキューム操作を必要とする代わりに、SELECT
を含む通常の操作中に完全に削除することができます。
(これはインデックスがページアイテム識別子を参照しないため可能です。)
要約すると、ヒープ専用タプル更新は、インデックスで使用されるカラムが更新されない場合にのみ作成できます。
テーブルのfillfactor
を減らすことで、HOT更新のための十分なページ領域の可能性を高めることができます。
そうしない場合でも、HOT更新は発生します。
なぜなら、新しい行は新しいページや、新しい行バージョンのために十分な空き領域を持つ既存のページに自然に移動するからです。
システムビューpg_stat_all_tablesは、HOTおよび非HOT更新の発生を監視することができます。