2015-07-10 319 views
7

我想了解列的顺序如何最小化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) 

元组大小:元组报头为NULL位图+ 1个字节的

23字节的开销,所以:

24 + 4 + 4 + 8 + 8 + 5 + 7 + 5 + 5 + 8 + 1 + 1 = 80,但实际的元组大小是82

是否有2字节的任何额外开销?

我明白以下链接给出的例子:
Calculating and saving space in 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 

PostgreSQL中的列顺序是否有任何建议?

回答

6

你错过另一个2个填充字节column_9 timestamp之前,其需要在8个字节的倍数开始。

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

相关答案:

+0

的固定大小的类型应放置如8-字节首然后加入4-字节然后是2个字节,然后是1个字节。什么样的变量大小类型如char(n),varchar(n),文本,数字(p,s)。我认为它的数字(p,s),char(n),varchar(n)然后是文本。我的理解是否正确? – user3756488

+0

@ user3756488:您可以混合不需要自由对齐的可变大小类型(选择有意义的顺序而不考虑存储)。只有需要对齐的类型才会产生差异,对齐可能需要填充。它还有助于性能(而不是存储)一点点地具有固定长度的非空列。 –

+0

谢谢Erwin Brandstetter。 – user3756488