我有一个简单的例子,其中 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。
第一个值是 TOAST 值的压缩大小,而第二个值是整行的未压缩大小。
\n\nSELECT \'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)\nRun Code Online (Sandbox Code Playgroud)\n\nfoo.*(或foo就此而言)是 PostgreSQL 中的“全行引用”,其数据类型是foo(在创建表时创建)。
PostgreSQL 知道它foo.bar存储在外部,因此它返回其大小,因为它在 TOAST 表中,但foo(复合类型)不是,因此您可以获得总大小。
请参阅以下的相关代码src/backend/access/heap/tuptoaster.c:
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)\nRun Code Online (Sandbox Code Playgroud)\n