我正在寻找通过引用列类型和长度大小来获得预期的表大小。我正在尝试使用pg_column_size
。
在测试函数时,我意识到这个函数似乎有问题。
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)
这是错误还是什么?是否有人使用某些公式从列类型和长度值计算预期的表大小?
答案 0 :(得分:12)
我说pg_column_size
报告TOAST
ed值的压缩大小,而octet_length
报告未压缩的大小。我还没有通过检查函数源或定义来验证这一点,但它是有意义的,特别是因为数字串会很好地压缩。您正在使用EXTENDED
存储空间,因此这些值适用于TOAST
压缩。请参阅the TOAST
documentation。
至于计算预期的DB大小,这是一个全新的问题。从下面的演示中可以看出,它取决于字符串的可压缩性等。
这里有一个演示,展示了octet_length
如何大于pg_column_size
,展示了TOAST开始的地方。首先,让我们在查询输出中得到结果,其中{{1}开始发挥作用:
TOAST
现在让我们将相同的查询输出存储到表中并获取存储行的大小:
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)