2015-07-10 18 views
7

Tôi đang cố gắng hiểu cách thứ tự cột giảm thiểu kích thước bảng trong PostgreSQL.Tính kích thước tuple

Ví dụ:

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) 

Các tuple kích thước:

23 byte overhead header tuple + 1 byte cho NULL bitmap, vì vậy:

24 + 4 + 4 + 8 + 8 + 5 + 7 + 5 + 5 + 8 + 1 + 1 = 80 nhưng kích thước tuple thực tế là 82.

Có thêm chi phí nào là 2 byte không?

tôi hiểu các ví dụ được đưa vào bên dưới liên kết:
Calculating and saving space in PostgreSQL

Nếu chúng ta loại bỏ các column_8 numeric(5,2) sau đó cũng kích thước tuple vẫn giữ nguyên, tức là: 82.

Tôi có sắp xếp lại bảng để giảm thiểu kích thước tuple và cung cấp cho 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 

Có đề xuất nào về thứ tự cột trong PostgreSQL không?

Trả lời

6

Bạn đã bỏ lỡ 2 byte đệm khác trước column_9 timestamp, cần phải bắt đầu với bội số là 8 byte.

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 

Đó cũng là lý do cho việc này:

Nếu chúng ta loại bỏ các column_8 numeric(5,2) sau đó cũng kích thước tuple vẫn giữ nguyên, tức là: 82.

Sau đưa ra cột đó chiếm 5 byte bạn nhận được 7 byte đệm tại cùng một chỗ - trường hợp xấu nhất. Cũng cần lưu ý rằng hàng này thực sự chiếm 88 bytes trên đĩa, vì tiêu đề bộ tuple của bộ tiếp theo được căn trái (bắt đầu từ bội số của MAXALIGN, thường là 8 byte).

Hàng đã sửa đổi của bạn kết thúc ở bội số của 8 byte không phải chịu thêm phần đệm và chỉ cần 80 byte.

Cả hai cần thêm 4 byte nữa cho con trỏ tuple trong tiêu đề trang.

Đó là trò chơi "cột tetris", những điều cơ bản mà bạn có vẻ đã hiểu. Thông thường bạn sẽ không đạt được nhiều, đừng nghĩ quá nhiều về nó. Tuy nhiên, có những trường hợp góc cực đoan. Các giá trị rỗng thay đổi trò chơi mỗi hàng.

Bạn cần biết các yêu cầu kích thước, căn chỉnh và đệm cho từng loại dữ liệu và các quy tắc đặc biệt cho bitmap NULL.

câu trả lời liên quan với tính toán chi tiết trên dba.SE:

+0

Các loại kích thước cố định nên được đặt như 8-byte đầu tiên sau đó 4 byte sau đó 2 byte và sau đó 1 byte. Điều gì về loại kích thước biến như char (n), varchar (n), văn bản, số (p, s). Tôi nghĩ rằng số của nó (p, s), char (n), varchar (n) và sau đó văn bản. Tôi hiểu có đúng không? – user3756488

+0

@ user3756488: Bạn có thể kết hợp các loại kích thước khác nhau mà không cần phải căn chỉnh một cách tự do (đã chọn một thứ tự có ý nghĩa mà không quan tâm đến việc lưu trữ). Chỉ có các loại cần được căn chỉnh tạo nên sự khác biệt trong căn chỉnh đó có thể yêu cầu đệm. Nó cũng giúp hiệu năng (không lưu trữ) một chút xíu để có các cột có độ dài cố định, không null trước. –

+0

Cảm ơn Erwin Brandstetter. – user3756488

Các vấn đề liên quan