Không có gì đáng ngạc nhiên, hướng dẫn là đúng. Nhưng có nhiều hơn cho nó.
Đối với một, kích thước trên đĩa (trong bất kỳ bảng nào , ngay cả khi không thực sự được lưu trữ trên đĩa) có thể khác với kích thước trong bộ nhớ . Trên đĩa, chi phí chung cho varchar
các giá trị ngắn lên tới 126 byte được giảm xuống còn 1 byte như được nêu trong hướng dẫn. Nhưng tổng phí trong bộ nhớ luôn là 4 byte (một khi các giá trị riêng lẻ được trích xuất).
Điều này cũng đúng đối với text
, varchar
, varchar(n)
hoặcchar(n)
- ngoại trừ việc char(n)
là trống-đệm để n
nhân vật và bạn thường không muốn sử dụng nó. Kích thước hiệu quả của nó vẫn có thể thay đổi trong mã hóa nhiều byte vì n
biểu thị tối đa các ký tự, không phải byte:
chuỗi dài đến n
ký tự (không phải byte).
Tất cả đều sử dụng varlena
nội bộ.
"char"
(với dấu ngoặc kép) là một sinh vật khác nhau và luôn chiếm một byte đơn.
Chuỗi ký tự không được đánh dấu ( 'foo'
) có một byte trên đầu. Đừng nhầm lẫn với các giá trị đánh máy!
Kiểm tra với pg_column_size()
.
CREATE TEMP TABLE t (id int, v_small varchar, v_big varchar);
INSERT INTO t VALUES (1, 'foo', '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890');
SELECT pg_column_size(id) AS id
, pg_column_size(v_small) AS v_small
, pg_column_size(v_big) AS v_big
, pg_column_size(t) AS t
FROM t
UNION ALL -- 2nd row measuring values in RAM
SELECT pg_column_size(1)
, pg_column_size('foo'::varchar)
, pg_column_size('12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'::varchar)
, pg_column_size(ROW(1, 'foo'::varchar, '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'::varchar));
id | v_small | v_big | t
----+---------+-------+-----
4 | 4 | 144 | 176
4 | 7 | 144 | 176
Bạn có thể thấy:
- Chuỗi 3 byte 'foo' chiếm 4 byte trên đĩa và 7 byte trong RAM (vì vậy 1 byte so với 4 byte trên không).
- Chuỗi 140 byte '123 ...' chiếm 144 byte cả trên đĩa và trong RAM (vì vậy luôn có 4 byte trên không).
- Lưu trữ
integer
không có chi phí hoạt động (nhưng nó có các yêu cầu căn chỉnh có thể áp đặt phần đệm).
- Hàng có tổng phí bổ sung là 24 byte cho tiêu đề tuple (cộng thêm 4 byte cho mỗi tuple cho con trỏ mục trong tiêu đề trang).
- Và cuối cùng nhưng không kém phần quan trọng: Chi phí nhỏ
varchar
vẫn chỉ là 1 byte trong khi nó chưa được trích xuất từ hàng - như có thể thấy từ kích thước hàng. (Đó là lý do tại sao đôi khi nhanh hơn một chút để chọn toàn bộ hàng.)
Liên quan: