PostgreSQL新建空表为何data_size为0但total_size达32KB?
问题描述
使用以下语句创建了一张空表(未插入任何记录):
LIKE prod_events INCLUDING ALL
原表prod_events包含索引和JSONB列。执行查询语句:
select schemaname as table_schema, relname as table_name, pg_size_pretty(pg_total_relation_size(relid)) as total_size, pg_relation_size(relid) as data_size, pg_size_pretty(pg_total_relation_size(relid) - pg_relation_size(relid)) as external_size from pg_catalog.pg_statio_user_tables order by pg_total_relation_size(relid) desc, pg_relation_size(relid) desc limit 10;
结果显示新表的data_size为0,但total_size和external_size为32KB,使用的PostgreSQL版本为13.15,请问该现象的原因是什么?
原因分析
pg_relation_size(relid)仅计算主表本身的磁盘占用,由于新表未插入任何数据,主表没有存储数据的磁盘块,因此显示为0。pg_total_relation_size(relid)统计的是主表+所有关联对象(索引、TOAST表)的总磁盘大小。你使用INCLUDING ALL创建表时,会完整复制原表的所有索引、约束以及TOAST表结构:- 空索引在PostgreSQL中会占用至少一个8KB的默认磁盘块(如果原表有多个索引,多个块的大小会累加)。
- 原表的JSONB列会触发TOAST表的创建(用于存储大字段溢出数据),即使新表没有数据,TOAST表本身也会占用初始的磁盘块。
external_size是总大小减去主表大小,也就是索引和TOAST表的总占用,因此显示为32KB。
内容的提问来源于stack exchange,提问作者Jayadevan
相关产品推荐
相关产品推荐

