来自PG DOC
pg_column_size(any) :用于存储特定值的字节数(可能已压缩) pg_column_size 显示用于存储任何单个数据值的空间
例子:
select pg_column_size(5::smallint); -- 2 bytes
select pg_column_size(5::int); -- 4 bytes
使用 pg_column_size 的输入,它可以是列或行,所以我创建了一个测试来检查它。这是我的测试:
我的桌子
CREATE TABLE index_test
(
id integer NOT NULL, -- 4 bytes
a integer, -- 4 bytes
b integer, -- 4 bytes
CONSTRAINT index_test_id PRIMARY KEY (id)
)
1/ 第一个查询: sum(pg_column_size(table.rows))
with abc as
(
select id,a,b
from index_test where b > 100
)
select pg_size_pretty(sum(pg_column_size(abc.*))) from abc -- "348 kB", abc.* = record
和查询的解释:
"Aggregate (cost=427.55..427.56 rows=1 width=24) (actual time=9.171..9.171 rows=1 loops=1)"
" CTE abc"
" -> Seq Scan on index_test (cost=0.00..180.00 rows=9902 width=12) (actual time=0.039..2.882 rows=9902 loops=1)"
" Filter: (b > 100)"
" -> CTE Scan on abc (cost=0.00..198.04 rows=9902 width=24) (actual time=0.047..7.151 rows=9902 loops=1)"
"Total runtime: 9.376 ms"
2/ 第二个查询: sum(pg_column_size(table.id)) + sum(pg_column_size(table.a)) + sum(pg_column_size(table.b))
with abc as
(
select id, a, b
from index_test where b > 100
)
select pg_size_pretty((sum(pg_column_size(id))) + (sum(pg_column_size(b))) + (sum(pg_column_size(a))))
from abc -- "116 kB"
和查询的解释:
"Aggregate (cost=526.57..526.59 rows=1 width=12) (actual time=10.959..10.959 rows=1 loops=1)"
" CTE abc"
" -> Seq Scan on index_test (cost=0.00..180.00 rows=9902 width=12) (actual time=0.035..2.780 rows=9902 loops=1)"
" Filter: (b > 100)"
" -> CTE Scan on abc (cost=0.00..198.04 rows=9902 width=12) (actual time=0.039..5.623 rows=9902 loops=1)"
"Total runtime: 11.173 ms"
3/ 结果:
第一个查询:348 KB
第二个查询:116 KB ( pg_column_size(id) = 39 KB ...)
我认为两个查询都必须返回相同的结果,但是第一个查询的大小 = 3 * 第二个查询的大小,这让我感到困惑。在第一个解释中,“宽度 = 24 字节/行”(而不是 12),我想知道它为什么会增加,我认为这是问题的线索。到目前为止,我无法找到我的问题的明确答案,请帮助我。
24 字节/行的差异敲响了警钟:它与表和索引中的行标题大小相同。直到您提出问题,我才意识到相同的标题大小显然适用于您在查询中返回的每一行:
但
将行传递给 时
pg_column_size()
,它会计算整行的大小,包括标题。现在进一步玩这个,你可以找到一些有趣的事实。
例如,可以检查将列填充到最接近的 4 个字节(其中 k 是正整数)引起的差异:
这里我们比第一个例子多了两个字节,smallint 之后剩下的 2 个字节被“浪费”了。这在选择大表中的列顺序时可能很重要——例如,我们可以将一些东西挤进那个“空白”空间:
另一个重要的事情是,具有 NULL 作为值的列在这里的大小为零:
相反,当您尝试单独添加列时,您会得到 NULL: