2015-07-10 311 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