2014-08-20 8:22 GMT-03:00 Alessandro Lima <[email protected]>:
> 1- uma tabela com 27435 registros com índice (integer 4 bytes) consome
> 616KB, sendo que 27435 x 4B = 107KB, esta diferença (overhead) é normal?
> tem alguma fórmula matemática para calcular o tamanho de índices?
>
>
Sim, é normal. Isso porque você está desconsiderando vários fatores.
Primeiro, as tuplas numa tabela (vamos desconsiderar índices por enquanto)
estão dispostas em páginas de 8KB, sendo que cada página possui cabeçalho
(header) e pointeiros para as páginas, algo como:
([header][ptr][ptr][ptr] ... <espaço vazio> ... [tupla][tupla][tupla])
Acima é possível que uma página completamente cheia ainda tenha um espaço
em branco, seja devido à nenhuma tupla+ptr caber nesse espaço ou devido ao
fill_factor (que por padrão não alteraria). Além de espaço sendo ocupados
por tuplas mortas, que serão marcadas pelo VACUUM tornando-se espaço vazio
e que só serão ocupados em novas operações de INSERT ou UPDATE.
Segundo, temos que considerar também que cada tupla possui também um
cabeçalho. O cabeçalho ocupa ao menos 27 bytes, geralmente vai ser mais
devido ao alinhamento [1] e ao bitmap de valores NULLs. Detalhes em [2].
Agora, se formos considerar índices, a coisa complica bem mais. Pensando em
B-trees temos várias sobrecargas, além dos cabeçalhos, cada valor de um nó
folha (onde estão os dados) tem um ponteiro para a tupla (cerca de 6-8
bytes se não me engano), tem também os nós intermediários (ao menos o nó
raiz existirá) e ainda o fill_factor dos índices que é menor por padrão.
Fora inchaço.
2- Somando o tamanho (informado pelo pgadmin) das colunas:
> integer:,média 4B
> varchar: média 14B
> varchar: média 19B
> varchar: média 12B
> ----------------------------
> total: média 49B
> 27435 x 49B = 1,28MB, o pgadmin informa que a tabela (sem índices) consome
> 2,18MB
>
>
Além dos "overheads" que comentei acima, tem mais o alinhamento de bytes
[1].
Veja também a apresentação do Bruce Monjian "PostgreSQL Internals Through
Pictures", em [3].
> 3- Somando todas as tabelas (incluindo toast e índices) informados pelo
> próprio pgadmin, o tamanho seria de 3,1MB mas o tabanho da base completa é
> de 9.56MB
>
Você considerou tabelas de catálogo? Não sei como o pgAdmin calcula isso,
então fica difícil dizer. Eu diria que as duas consultas abaixo deveriam
retornar valores bem próximos:
SELECT pg_size_pretty(sum(pg_relation_size(oid))) FROM pg_class;
SELECT pg_size_pretty(pg_database_size(current_database()));
Como deve ter notado, não são contas triviais. Na verdade não são exatas,
pois muitas coisas temos que explorar mais baixo nível para encontrar.
Algumas contribs como pageinspect e freespacemap ajudam nisso.
[1] http://en.wikipedia.org/wiki/Data_structure_alignment
[2] http://www.postgresql.org/docs/current/static/storage-page-layout.html
[3] http://www.postgresql.org/files/developer/internalpics.pdf
Atenciosamente,
--
Matheus de Oliveira
Analista de Banco de Dados
Dextra Sistemas - MPS.Br nível F!
www.dextra.com.br/postgres
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral