別の質問 では、スペースを節約し、パフォーマンスを向上させるために、テーブルの1つからレイアウトを最適化する必要があることを学びました。私はこれを行いましたが、以前よりも大きなテーブルになり、パフォーマンスは変わりませんでした。もちろん、_VACUUM ANALYZE
_を実行しました。どうして?
(単一の列にのみインデックスを付けた場合、インデックスのサイズは変更されません。)
これは私が使っていたテーブルです(サイズとパディングを追加しました):
_ Table "public.treenode"
Column | Type | Size | Modifiers
---------------+--------------------------+------+-------------------------------
id | bigint | 8 | not null default nextval( ...
user_id | integer | 4+4 | not null
creation_time | timestamp with time zone | 8 | not null default now()
edition_time | timestamp with time zone | 8 | not null default now()
project_id | integer | 4 | not null
location | real3d | 36 | not null
editor_id | integer | 4+4 |
parent_id | bigint | 8 |
radius | real | 4 | not null default 0
confidence | smallint | 2 | not null default 5
skeleton_id | integer | 4 | not null
_
_real3d
_が次のように定義されている場合
_CREATE TYPE real3d AS (
x real,
y real,
z real);
_
このレイアウトを次のように変更しました。
_ Table "public.treenode_new"
Column | Type | Size | Modifiers
---------------+--------------------------+------+--------------------------------
id | bigint | 8 | not null default nextval(' ...
project_id | integer | 4 | not null
location_x | real | 4 | not null
location_y | real | 4 | not null
location_z | real | 4 | not null
editor_id | integer | 4 | not null
user_id | integer | 4 | not null
creation_time | timestamp with time zone | 8 | not null default now()
edition_time | timestamp with time zone | 8 | not null default now()
skeleton_id | integer | 4 | not null
radius | real | 4 | not null default 0
confidence | real | 4+4 | not null default 5
parent_id | bigint | 8 |
_
私が間違っていない場合は、1行あたり66バイトを節約する必要があります(138は元の1行、72は新しい行です)。ただし、これは発生していません。これらのテーブルに7604913がある場合、元のテーブルのサイズは1020 MBでした。新しいテーブルのサイズは1159 MBです。サイズの測定にはpg_size_pretty(pg_relation_size('<tablename>'))
を使用しました。では、何が欠けているのでしょうか?
注:最後の4つの列以外はすべて別のテーブルから継承されます(もちろん、私もレイアウトを変更する必要がありました)。
更新:Erwin Brandstetterの提案に従って_VACUUM FULL
_を実行した後、新しいテーブルに必要なのは734 MBだけです。
物理テーブルのサイズは通常、VACUUM
(またはVACUUM ANALYZE
)を実行しても削減されません(テーブルの末尾からのリムーバブルページの日和見主義的プルーニングを除く)。実際にテーブルを縮小するには、 VACUUM FULL
を実行する必要があります。
テーブルに書き込み負荷がある場合、これは必ずしも定期的に実行したいことではありません。デッド行は、UPDATEが更新された行のバージョンを同じデータページに配置するための小刻みな余裕を提供し、これによりパフォーマンスが向上します。リレーションの物理テーブルを縮小および拡大するためのコストもあります。さらに、VACUUM FULL
は、テーブルの排他ロックを取り出します。
そのため、自動バキュームはVACUUM
(およびANALYZE
)のみを実行し、VACUUM FULL
は実行しません。
ただし、読み取り専用(またはほとんど読み取り)のテーブルは、最小サイズに保つのが最適です。また、テーブル定義を変更した後(またはその他の理由で)の過度の膨張は、すぐに削除することもできます。
テーブルの両方のバージョンでVACUUM FULL
を試して、もう一度測定してください。違いがわかるはずです。
行/テーブルのサイズの詳細については、 複数のテストを使用したクエリ を試すこともできます。