Postgresql
為什麼 pg_table_size 返回的每行大小大於 pg_column_size(row)?
我有一個只有整數和小整數列的表,最多加起來 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擴展來詳細檢查數據頁面。