2012-08-27 32 views
18

Tôi có một bảng có 7 cột và 5 cột trong số đó sẽ là rỗng. Tôi sẽ có một cột trống trên int, text, date, booleanmoney loại dữ liệu. Bảng này sẽ chứa hàng triệu hàng có nhiều null. Tôi sợ rằng các giá trị null sẽ chiếm không gian.Các cột rỗng có chiếm không gian bổ sung trong PostgreSQL không?

Ngoài ra, bạn có biết liệu Postgres có lập chỉ mục giá trị null không? Tôi muốn ngăn chặn nó lập chỉ mục null.

Trả lời

34

Về cơ bản, NULL giá trị chiếm 1 bit trong bitmap NULL. Nhưng nó không đơn giản như vậy.

bitmap (mỗi hàng) chỉ có ở đó nếu ít nhất một cột trong hàng đó giữ giá trị NULL. Điều này có thể dẫn đến một hiệu ứng nghịch lý trong các bảng có từ 9 cột trở lên: gán giá trị NULL đầu tiên cho một cột có thể chiếm nhiều không gian hơn trên đĩa hơn là viết một giá trị cho nó. Ngược lại, với cột cuối cùng trở thành không rỗng, bitmap rỗng sẽ bị xóa cho hàng.

Thể chất, null bitmap ban đầu chiếm 1 byte giữa HeapTupleHeader (23 byte) và dữ liệu cột thực tế hoặc hàng OID (nếu bạn vẫn nên sử dụng đó) - mà luôn bắt đầu tại một bội số của MAXALIGN (thường là 8 byte). Điều này để lại 1 byte của phần đệm được sử dụng bởi bitmap rỗng ban đầu.

Có hiệu lực Bộ nhớ NULL hoàn toàn miễn phí đối với các bảng gồm 8 cột hoặc ít hơn.
Sau đó, MAXALIGN byte (thông thường 8) khác được cấp cho MAXALIGN * 8 cột tiếp theo (thường là 64). Vv

Chi tiết in the manual và theo các câu hỏi liên quan:

Một khi bạn hiểu đệm liên kết của các kiểu dữ liệu, bạn có thể tiếp tục tối ưu hóa lưu trữ :

Nhưng các trường hợp rất hiếm, nơi bạn có thể tiết kiệm một số tiền lớn của không gian. Thông thường nó không đáng để thử.

@Daniel đã bao gồm các hiệu ứng trên kích thước chỉ mục.

+0

"Bộ nhớ NULL hoàn toàn miễn phí đối với các bảng có 8 cột trở xuống". - Điều gì sẽ xảy ra nếu chỉ có 1 cột giữ giá trị rỗng? điều này có nghĩa là bitmap rỗng với 1 byte sẽ được tạo chỉ để giữ 1 bit? – Dejell

+0

bitmap rỗng là có nếu có bất kỳ giá trị null, với đủ byte để bao gồm tất cả các cột, cộng với đệm để bội số tiếp theo của 'MAXALIGN'. –

+0

Cảm ơn Erwin. Vẫn không chắc chắn - nếu tôi không có bất kỳ giá trị null nào? nó vẫn ở đó chứ? (nhiều đến nhiều bảng) – Dejell

11

Giá trị NULL có được chỉ mục hay không phụ thuộc ít nhất vào loại chỉ mục. Về cơ bản, đây sẽ là YES cho btreegist loại chỉ số, NO cho hash, và có vẻ như YES hoặc NO cho gin loại chỉ số tùy thuộc vào phiên bản PostgreSQL.

Đã từng là cột boolean amindexnulls trong bảng pg_catalog.pg_am mang thông tin đó nhưng đã biến mất trong 9.1. Có lẽ vì các chỉ mục thậm chí còn tinh vi hơn trong các cải tiến PG.

Trong trường hợp cụ thể của dữ liệu, cách tốt nhất để biết là đo lường sự khác biệt về kích thước của chỉ mục, sử dụng hàm pg_relation_size('index_name'), giữa nội dung hoàn toàn NULL và hoàn toàn NOT NULL, với phiên bản PG chính xác, datatype chính xác, loại chỉ mục chính xác và định nghĩa. Và biết rằng có thể, một thay đổi trong tương lai trong bất kỳ tham số nào có thể thay đổi kết quả.

Nhưng trong mọi trường hợp, nếu bạn "chỉ là" muốn tránh NULLs lập chỉ mục, nó luôn luôn có thể tạo ra một chỉ số phần:

CREATE INDEX partial_idx(col) ON table WHERE (col is not null) 

Điều này sẽ mất ít không gian, nhưng liệu điều này sẽ trợ giúp hay không với hiệu suất của các truy vấn phụ thuộc vào các truy vấn này.

+7

+1 sâu sắc. Với các chỉ mục một phần, điều quan trọng cần lưu ý là chúng chỉ có thể được sử dụng bởi trình hoạch định truy vấn nếu nó có thể xác minh rằng điều kiện được bao hàm trong truy vấn. Trình lập kế hoạch truy vấn là thông minh, nhưng không giải quyết được logic phức tạp về mặt này. Phù hợp với mệnh đề 'WHERE' nhiều hoặc ít nguyên văn để đảm bảo chỉ mục có thể được sử dụng (có thể' AND'-ed với nhiều điều kiện hơn). [Chi tiết trong hướng dẫn] (http://www.postgresql.org/docs/current/interactive/indexes-partial.html). –

+0

Cool..Cảm ơn câu trả lời sâu sắc của bạn – Luke101

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