我有一个只有整数和小整数列的表,最多加起来 20 个字节。pg_column_size
报告 44. 由于每行开销 24 字节,这是预期的,如pg_column_size(table.*) 和 pg_column_size(table.col1) + pg_column_size (table.col2) 之间的差异中所述
但是,如果我除以pg_table_size
行数,我会得到每行约 53 个字节,即使有数亿行。这些额外的 9 个字节从何而来?
即使只有一个整数列,我也可以重现这一点:
drop table if exists anint;
create table anint
as
select generate_series
from generate_series(1, 10000000);
select pg_column_size(e.*) -- 28
from anint e
limit 1;
select n_live_tup as row_count_estimate, -- 10000000
pg_size_pretty(pg_table_size(relid)) as table_size, -- 346 MB
case when n_live_tup = 0 then null else pg_table_size(relid) / cast(n_live_tup as float) end as table_bytes_per_row -- 36.2561536
from pg_catalog.pg_statio_user_tables io
join pg_catalog.pg_stat_user_tables s using (relid)
where io.schemaname = 'public' and io.relname = 'anint'
这将返回 ~36 字节/行,而不是 28。(在 PostgreSQL 14.1 上测试。)
看一个 PostgreSQL 表页面的布局:
您正在测量的行大小是
Item
,但还有文档ItemId
中描述的(“行指针”):此外,还需要考虑页眉和对齐填充,并且每个块中总会留下一些空闲空间(任何小到无法容纳另一行的空间)。这可能足以解释差异。您可以使用pageinspect扩展来详细检查数据页面。