"Tetris cột"
Trên thực tế, bạn có thể làm điều gì đó , nhưng điều này cần hiểu sâu hơn. Từ khóa là đệm căn chỉnh . Mọi loại dữ liệu đều có các yêu cầu căn chỉnh cụ thể.
Bạn có thể giảm thiểu không gian bị mất để đệm giữa các cột bằng cách đặt hàng chúng một cách thuận lợi. Ví dụ (cực kỳ) sau sẽ lãng phí rất nhiều dung lượng đĩa vật lý:
CREATE TABLE t (
e int2 -- 6 bytes of padding after int2
, a int8
, f int2 -- 6 bytes of padding after int2
, b int8
, g int2 -- 6 bytes of padding after int2
, c int8
, h int2 -- 6 bytes of padding after int2
, d int8)
Để tiết kiệm 24 byte mỗi hàng, sử dụng thay thế:
CREATE TABLE t (
a int8
, b int8
, c int8
, d int8
, e int2
, f int2
, g int2
, h int2) -- 4 int2 occupy 8 byte (MAXALIGN), no padding at the end
db <> fiddle here
Sqlfiddle cũ
Theo quy tắc chung, nếu bạn đặt các cột 8 byte đầu tiên, sau đó đặt các cột 4 byte, 2 byte và 1 byte cuối cùng thì bạn không thể sai.
boolean
, uuid
(!) và một số loại khác không cần đệm căn chỉnh. text
, varchar
và các loại "varlena" (độ dài thay đổi) khác trên danh nghĩa yêu cầu căn chỉnh "int" (4 byte trên hầu hết các máy). Nhưng tôi quan sát thấy không có đệm căn chỉnh trong định dạng đĩa (không giống như trong RAM). Cuối cùng, tôi đã tìm thấy lời giải thích trong một ghi chú trong mã nguồn:
Cũng lưu ý rằng chúng tôi cho phép căn chỉnh danh nghĩa bị vi phạm khi lưu trữ các varlenas "được đóng gói"; cơ chế TOAST đảm nhận việc ẩn điều đó khỏi hầu hết các mã.
Vì vậy, căn chỉnh "int" chỉ được thực thi khi dữ liệu (có thể được nén) bao gồm một byte độ dài hàng đầu vượt quá 127 byte. Sau đó, bộ nhớ varlena chuyển sang bốn byte đứng đầu và yêu cầu căn chỉnh "int".
Thông thường, bạn có thể tiết kiệm một vài byte mỗi hàng khi phát tốt nhất "cột tetris" . Không điều nào trong số này là cần thiết trong hầu hết các trường hợp. Nhưng với hàng tỷ hàng, nó có thể có nghĩa là một vài gigabyte một cách dễ dàng.
Bạn có thể kiểm tra kích thước cột / hàng thực tế bằng hàm pg_column_size()
.
Một số loại chiếm nhiều dung lượng trong RAM hơn trên đĩa (định dạng nén hoặc "đóng gói"). Bạn có thể nhận được kết quả lớn hơn cho các hằng số (định dạng RAM) so với các cột trong bảng khi kiểm tra cùng một giá trị (hoặc hàng giá trị so với hàng bảng) với pg_column_size()
.
Cuối cùng, một số loại có thể được nén hoặc "nướng" (lưu trữ ngoài dòng) hoặc cả hai.
Chi phí trên mỗi tuple (hàng)
4 byte mỗi hàng cho số nhận dạng mục - không phụ thuộc vào các cân nhắc ở trên.
Và ít nhất 24 byte (23 + padding) cho tiêu đề bộ. Hướng dẫn về Bố cục Trang Cơ sở dữ liệu:
Có một tiêu đề kích thước cố định (chiếm 23 byte trên hầu hết các máy), theo sau là một bitmap rỗng tùy chọn, trường ID đối tượng tùy chọn và dữ liệu người dùng.
Đối với phần đệm giữa tiêu đề và dữ liệu người dùng, bạn cần biết MAXALIGN
trên máy chủ của bạn - thường là 8 byte trên HĐH 64 bit (hoặc 4 byte trên HĐH 32 bit). Nếu bạn không chắc chắn, hãy xem pg_controldata
.
Chạy phần sau trong Dir nhị phân Postgres của bạn để nhận được câu trả lời dứt khoát:
./pg_controldata /path/to/my/dbcluster
Hướng dẫn sử dụng:
Dữ liệu người dùng thực tế (các cột của hàng) bắt đầu từ phần được cung cấp bởi
t_hoff
, luôn phải là bội số củaMAXALIGN
khoảng cách cho nền tảng.
Vì vậy, bạn thường có được bộ nhớ tối ưu bằng cách đóng gói dữ liệu theo bội số của 8 byte.
Không có gì để đạt được trong ví dụ bạn đã đăng . Nó đã được đóng gói chặt chẽ. 2 byte đệm sau int2
cuối cùng , 4 byte ở cuối. Bạn có thể hợp nhất phần đệm thành 6 byte ở cuối, điều này sẽ không thay đổi bất cứ điều gì.
Chi phí trên mỗi trang dữ liệu
Kích thước trang dữ liệu thường là 8 KB. Một số overhead / bloat ở cấp độ này cũng vậy:Các phần còn lại không đủ lớn để phù hợp với một bộ khác và quan trọng hơn là các hàng chết hoặc tỷ lệ phần trăm được đặt trước với FILLFACTOR
cài đặt.
Có một số yếu tố khác về kích thước trên đĩa cần tính đến:
- Tôi có thể lưu trữ bao nhiêu bản ghi trong 5 MB PostgreSQL trên Heroku?
- Không sử dụng NULL trong PostgreSQL vẫn sử dụng bitmap NULL trong tiêu đề?
- Định cấu hình PostgreSQL để có hiệu suất đọc
Các loại mảng?
Với một mảng nhập như bạn đang đánh giá, bạn sẽ thêm 24 byte chi phí cho loại. Thêm vào đó, các phần tử mảng chiếm không gian như bình thường. Không có gì để đạt được ở đó.