Em outra questão aprendi que devo otimizar o layout de uma das minhas mesas para economizar espaço e ter melhor desempenho. Fiz isso, mas acabei com uma mesa maior do que antes e o desempenho não mudou. Claro que fiz um VACUUM ANALYZE
. Como assim?
(Vejo que os tamanhos de índice não serão alterados se eu indexar apenas colunas únicas.)
Esta é a tabela de onde eu vim (adicionei tamanhos + preenchimento):
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
Sendo real3d
definido como
CREATE TYPE real3d AS (
x real,
y real,
z real);
Alterei este layout para o seguinte:
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 |
Se não me engano, devo salvar 66 bytes por linha (138 é uma linha original, 72 é uma nova linha). Isso, porém, não está acontecendo: Com 7604913 nessas tabelas, a tabela original tinha um tamanho de 1020 MB. A nova tabela tem um tamanho de 1159 MB. Eu costumava pg_size_pretty(pg_relation_size('<tablename>'))
medir os tamanhos. Então, o que estou perdendo?
Uma observação: todas, exceto as últimas quatro colunas, são herdadas de outra tabela (da qual, é claro, também tive que alterar o layout).
Atualização: Depois de executar VACUUM FULL
conforme sugerido por Erwin Brandstetter, a nova tabela precisa de apenas 734 MB.
O tamanho da tabela física normalmente (exceto para remoção oportunista de páginas removíveis do final da tabela) não é reduzido pela execução
VACUUM
(ouVACUUM ANALYZE
). Você precisa correrVACUUM FULL
para realmente encolher a mesa.Isso não é necessariamente o que você deseja fazer regularmente se tiver carga de gravação em sua mesa. Linhas mortas fornecem espaço de manobra para UPDATEs colocar versões de linha atualizadas na mesma página de dados, o que permite um melhor desempenho. Há também um custo para encolher e aumentar a tabela física de uma relação. Além disso,
VACUUM FULL
tira uma trava exclusiva na mesa.É por isso que o autovacuum só funciona
VACUUM
(eANALYZE
) nãoVACUUM FULL
.No entanto, é melhor manter as tabelas somente leitura (ou principalmente lidas) em seu tamanho mínimo. E o inchaço excessivo após alterações na definição da tabela (ou por algum outro motivo) também deve ser removido imediatamente.
Experimente
VACUUM FULL
as duas versões da tabela e meça novamente. A diferença deve aparecer.Você também pode tentar minha consulta com vários testes para obter mais informações sobre tamanhos de linha/tabela.