use*_*488 7 postgresql storage database-design
我试图了解列顺序如何最小化PostgreSQL中的表大小.
例:
CREATE TABLE test (
column_1 int
,column_2 int
,column_3 bigint
,column_4 bigint
,column_5 text
,column_6 text
,column_7 numeric(5,2)
,column_8 numeric(5,2)
,column_9 timestamp
,column_10 boolean
,column_11 boolean
);
INSERT INTO test
VALUES(1,1,1,1,'test','test_1',12,12,current_timestamp,true,false);
SELECT pg_column_size(test.*) FROM test;
pg_column_size
----------------
82
(1 row)
Run Code Online (Sandbox Code Playgroud)
元组大小:
元组头的23字节开销+ NULL位图的1字节,因此:
24 + 4 + 4 + 8 + 8 + 5 + 7 + 5 + 5 + 8 + 1 + 1 = 80但实际元组大小为82.
是否有2字节的额外开销?
我理解下面链接给出的例子:
在PostgreSQL中计算和节省空间
如果我们删除column_8 numeric(5,2)那么那么元组大小保持不变,即:82.
我重新排序表以最小化元组大小并给出80.
CREATE TABLE test (
column_3 bigint
,column_4 bigint
,column_9 timestamp
,column_1 int
,column_2 int
,column_10 boolean
,column_11 boolean
,column_7 numeric(5,2)
,column_8 numeric(5,2)
,column_5 text
,column_6 text);
INSERT INTO test
VALUES(1,1,current_timestamp,1,1,true,false,12,12,'test','test_1');
SELECT pg_column_size(test) FROM test;
pg_column_size
----------------
80
Run Code Online (Sandbox Code Playgroud)
PostgreSQL中的列顺序是否有任何建议?
之前你错过了另外2个字节的填充column_9 timestamp,需要以8个字节的倍数开始.
Run Code Online (Sandbox Code Playgroud)24+4+4+8+8+5+7+5+5+8+1+1=80 but the actual tuple size is 82. ------------------^ <----- 2 bytes of padding here
这也是原因:
如果我们删除
column_8 numeric(5,2)那么那么元组大小保持不变,即:82.
取出占用5个字节的列后,在同一位置获得7个字节的填充 - 最坏的情况.
另请注意,此行实际占用磁盘上的88个字节,因为下一个元组的元组头是左对齐的(从多个开始MAXALIGN,通常是8个字节).
修改后的行以8个字节的倍数结束,不会产生额外的填充,只需要80个字节.
但是,两者都需要另外4个字节用于页眉中的元组指针.
这是一个"列俄罗斯方块"的游戏,你似乎已经理解了它的基础知识.通常情况下你不会获得太多收益,不要过于考虑它.但是,有极端的角落案件.空值会改变每行的游戏.
您需要知道每种数据类型的大小,对齐和填充要求以及NULL位图的特殊规则.
关于dba.SE的详细计算的相关答案:
| 归档时间: |
|
| 查看次数: |
2369 次 |
| 最近记录: |