You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不使用PL/pgSQL动态查询,通过纯SQL获取PostgreSQL表主键列的总大小

纯SQL实现主键列总大小计算

当然有办法!你完全可以用纯SQL来实现这个需求,不需要依赖PL/pgSQL的动态查询。下面是两种可靠的实现方案:

方案一:利用JSONB提取主键列(推荐)

这个方法通过将行转换为JSON,提取出主键对应的字段后计算大小,逻辑清晰且兼容性好:

WITH pk_columns AS (
    -- 获取目标表的所有主键列名数组
    SELECT array_agg(a.attname) AS pk_col_names
    FROM pg_index i
    JOIN pg_attribute a 
        ON a.attrelid = i.indrelid 
        AND a.attnum = ANY(i.indkey)
    WHERE i.indrelid = 'public.my_test'::regclass
      AND i.indisprimary
)
SELECT 
    COALESCE(SUM(
        pg_column_size(
            -- 提取每行的主键列组成的JSONB对象
            jsonb_extract_path(
                pg_row_to_json(t),
                VARIADIC pk_col_names
            )
        )
    ), 0) AS total_primary_key_size
FROM public.my_test t, pk_columns;

原理说明:

  1. 先用CTE pk_columns 查询系统表,拿到目标表的主键列名数组。
  2. 对表中每一行,用pg_row_to_json把整行转为JSON格式。
  3. 用jsonb_extract_path结合VARIADIC关键字,传入主键列名数组,提取出仅包含主键列的JSONB对象。
  4. 用pg_column_size计算这个JSONB对象的大小(等同于该行所有主键列的大小之和),最后求和所有行的结果,COALESCE确保空表返回0而非NULL。

方案二:利用HStore提取主键列

如果你的环境中已经启用了hstore扩展,也可以用这种方式:

-- 先确保hstore扩展已启用(首次使用需执行)
-- CREATE EXTENSION IF NOT EXISTS hstore;

WITH pk_columns AS (
    SELECT array_agg(a.attname) AS pk_col_names
    FROM pg_index i
    JOIN pg_attribute a 
        ON a.attrelid = i.indrelid 
        AND a.attnum = ANY(i.indkey)
    WHERE i.indrelid = 'public.my_test'::regclass
      AND i.indisprimary
)
SELECT 
    COALESCE(SUM(pg_column_size(hstore(t) #> pk_col_names)), 0) AS total_primary_key_size
FROM public.my_test t, pk_columns;

原理说明:

  1. 同样先获取主键列名数组。
  2. 用hstore(t)把行转为键值对格式的hstore对象。
  3. 用#>操作符提取主键列对应的hstore子集,计算其大小后求和。

这两种方案都和你原来的PL/pgSQL逻辑完全一致:都是逐行计算所有主键列的大小之和,再汇总所有行的结果,而且完全不需要动态SQL。

内容的提问来源于stack exchange,提问作者Oto Shavadze

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 09:02:40