PostgreSQL pg_column_size() 函数使用指南
PostgreSQL pg_column_size() 是一个非常实用的存储诊断函数。与计算字符长度的 length() 或计算字符串字节长度的 octet_length() 不同,pg_column_size() 衡量的是任意具体数据值在物理磁盘和内存内部被 PostgreSQL 实际存储时所占用的真实物理字节数(包含类型头部、对齐填充以及 TOAST 压缩开销)。
在大规模高并发表结构设计、行宽(Row Width)预估、以及评估 JSONB / TEXT 字段压缩效率时,pg_column_size() 提供了无可替代的微观观察视角。
PostgreSQL pg_column_size() 语法
这里是 PostgreSQL pg_column_size() 函数的标准语法:
pg_column_size(any)
参数
any- 必需的。任意类型的 SQL 表达式、常量值或数据表字段引用。
返回值
返回一个 integer 整数,表示存储该指定值所需的物理字节总数:
- 若参数为
NULL,返回NULL。 - 对于变长类型(如
varchar、text、jsonb、bytea),返回值包含了该数值的变长头部(1 或 4 字节)。 - 如果数据值过大被压缩存储(TOAST Compression),返回值体现的是压缩后的真实存储体积,而非解压后的原始文本大小。
PostgreSQL pg_column_size() 示例
以下示例演示定长类型与变长类型在底层存储中的真实字节消耗。
基础数据类型的存储字节数
比较不同数值与布尔类型的真实占用:
SELECT
pg_column_size(true) AS bool_size,
pg_column_size(12::smallint) AS smallint_size,
pg_column_size(12::integer) AS int_size,
pg_column_size(12::bigint) AS bigint_size,
pg_column_size(12.34::numeric) AS numeric_size,
pg_column_size('2026-11-14'::date) AS date_size;
输出:
bool_size | smallint_size | int_size | bigint_size | numeric_size | date_size
-----------+---------------+----------+-------------+--------------+-----------
1 | 2 | 4 | 8 | 11 | 4从测试可见,numeric 虽然能够提供任意高精度的数学计算,但其底层存储开销(11 字节)显著高于定长整数(4 或 8 字节)。
观测变长文本与 TOAST 压缩效果
观察不同长度文本及重复字符在 PostgreSQL 内部的压缩表现:
SELECT
octet_length('Hello PostgreSQL') AS raw_bytes,
pg_column_size('Hello PostgreSQL') AS stored_with_header,
octet_length(repeat('DatabaseTutorials', 500)) AS uncompressed_bytes,
pg_column_size(repeat('DatabaseTutorials', 500)) AS toast_compressed_bytes;
输出:
raw_bytes | stored_with_header | uncompressed_bytes | toast_compressed_bytes
-----------+--------------------+--------------------+------------------------
18 | 19 | 8500 | 142从结果可以看出:
- 对于短字符串
'Hello PostgreSQL',物理存储使用了 18 字节原始字符 + 1 字节短变长头部 = 19 字节; - 对于长达 8500 字节的重复文本,PostgreSQL 自动触发了内核内置的高效压缩算法,实际仅占用 142 字节!
结论
pg_column_size()反映的是底层物理事实,是判断字段是否被过度膨胀或是否成功享受压缩的核心工具。- 在优化宽表(Wide Tables)时,通过
SELECT avg(pg_column_size(col)) FROM table;可以快速摸排各字段对每行总体积的贡献度,精准确定瘦身目标。