14

我正在寻找通过引用列类型和长度大小来获得预期的表格大小。我正在尝试使用pg_column_size它。

在测试该功能时,我意识到此功能似乎有问题。

from 的结果值pg_column_size(...)有时甚至小于octet_length(...)同一字符串的返回值。

列中只有数字字符。

postgres=# \d+ t5
                           Table "public.t5"
 Column |       Type        | Modifiers | Storage  | Stats target | Description 
--------+-------------------+-----------+----------+--------------+-------------
 c1     | character varying |           | extended |              | 
Has OIDs: no

postgres=# select pg_column_size(c1), octet_length(c1) as octet from t5;
 pg_column_size | octet 
----------------+-------
              2 |     1
            704 |   700
            101 |  7000
            903 | 77000
(4 rows)

这是错误还是什么?是否有人有一些公式可以根据列类型和长度值计算预期的表大小?

4

1 回答 1

20

我想说pg_column_size的是报告TOASTed 值的压缩大小,而octet_length报告未压缩的大小。我还没有通过检查函数源或定义来验证这一点,但这是有道理的,尤其是当数字字符串压缩得很好时。您正在使用EXTENDED存储,因此这些值符合TOAST压缩条件。TOAST参阅文档

至于计算预期的数据库大小,这是一个全新的问题。正如您从以下演示中看到的那样,这取决于字符串的可压缩性等因素。

这是一个演示如何octet_length大于pg_column_size,演示 TOAST 的作用。首先,让我们在查询输出中获取 noTOAST起作用的结果:

regress=> SELECT octet_length(repeat('1234567890',(2^n)::integer)), pg_column_size(repeat('1234567890',(2^n)::integer)) FROM generate_series(0,12) n;
 octet_length | pg_column_size 
--------------+----------------
           10 |             14
           20 |             24
           40 |             44
           80 |             84
          160 |            164
          320 |            324
          640 |            644
         1280 |           1284
         2560 |           2564
         5120 |           5124
        10240 |          10244
        20480 |          20484
        40960 |          40964
(13 rows)

现在让我们将相同的查询输出存储到表中并获取存储行的大小:

regress=> CREATE TABLE blah AS SELECT repeat('1234567890',(2^n)::integer) AS data FROM generate_series(0,12) n;
SELECT 13

regress=> SELECT octet_length(data), pg_column_size(data) FROM blah;
 octet_length | pg_column_size 
--------------+----------------
           10 |             11
           20 |             21
           40 |             41
           80 |             81
          160 |            164
          320 |            324
          640 |            644
         1280 |           1284
         2560 |             51
         5120 |             79
        10240 |            138
        20480 |            254
        40960 |            488
(13 rows)
于 2012-11-09T08:37:36.310 回答