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; 可以快速摸排各字段对每行总体积的贡献度,精准确定瘦身目标。