pg_column_size 报告 table.* 的大小与特定列的大小差异很大

And*_*rew 5 postgresql

我有一个简单的例子,其中 pg_column_size 报告的值截然不同。我认为这与是否考虑 TOAST 值有关,但我不确定。这是设置:

CREATE TABLE foo (bar TEXT);
INSERT INTO foo (bar) VALUES (repeat('foo', 100000));
SELECT pg_column_size(bar) as col, pg_column_size(foo.*) as table FROM foo;
Run Code Online (Sandbox Code Playgroud)

我在 Postgres 9.6 中看到的是,

col     table
3442    300028
Run Code Online (Sandbox Code Playgroud)

这里有一个数量级的差异。想法?我计算行大小的正确方法是什么?我的一个想法是,

SELECT pg_column_size(bar), pg_column_size(foo.*) - octet_length(bar) + pg_column_size(bar) FROM foo;
Run Code Online (Sandbox Code Playgroud)

这应该减去后 TOAST 大小并添加 TOAST 大小。

编辑:我建议的解决方法仅适用于字符列,例如不适用于 JSONB。

Lau*_*lbe 5

第一个值是 TOAST 值的压缩大小,而第二个值是整行的未压缩大小。

\n\n
SELECT \'foo\'::regclass::oid;\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82  oid  \xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xa4\n\xe2\x94\x82 36344 \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n(1 row)\n\nSELECT sum(length(chunk_data)) FROM pg_toast.pg_toast_36344;\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82 sum  \xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xa4\n\xe2\x94\x82 3442 \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n(1 row)\n
Run Code Online (Sandbox Code Playgroud)\n\n

foo.*(或foo就此而言)是 PostgreSQL 中的“全行引用”,其数据类型是foo(在创建表时创建)。

\n\n

PostgreSQL 知道它foo.bar存储在外部,因此它返回其大小,因为它在 TOAST 表中,但foo(复合类型)不是,因此您可以获得总大小。

\n\n

请参阅以下的相关代码src/backend/access/heap/tuptoaster.c

\n\n
SELECT \'foo\'::regclass::oid;\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82  oid  \xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xa4\n\xe2\x94\x82 36344 \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n(1 row)\n\nSELECT sum(length(chunk_data)) FROM pg_toast.pg_toast_36344;\n\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82 sum  \xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xa4\n\xe2\x94\x82 3442 \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n(1 row)\n
Run Code Online (Sandbox Code Playgroud)\n