Postgresql

為什麼 pg_table_size 返回的每行大小大於 pg_column_size(row)?

  • December 23, 2021

我有一個只有整數和小整數列的表,最多加起來 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中描述的(“行指針”):

ItemIdData:指向實際項目的項目標識符數組。每個條目都是一個(偏移量,長度)對。每個項目 4 個字節。

此外,還需要考慮頁眉和對齊填充,並且每個塊中總會留下一些空閒空間(任何小到無法容納另一行的空間)。這可能足以解釋差異。您可以使用pageinspect擴展來詳細檢查數據頁面。

引用自:https://dba.stackexchange.com/questions/305331