Quý 2: way to measure page size
PostgreSQL cung cấp một số Hàm Kích thước Đối tượng Cơ sở dữ liệu . Tôi đã đóng gói những cái thú vị nhất trong truy vấn này và thêm một số Hàm truy cập thống kê ở phía dưới. (Các pgstattuple mô-đun bổ sung cung cấp nhiều chức năng hữu ích hơn.)
Điều này sẽ cho thấy rằng các phương pháp khác nhau để đo "kích thước của một hàng" dẫn đến kết quả rất khác nhau. Tất cả phụ thuộc vào những gì bạn muốn đo, chính xác.
Truy vấn này yêu cầu Postgres 9.3 trở lên . Đối với các phiên bản cũ hơn xem bên dưới.
Sử dụng một VALUES
biểu thức trong LATERAL
truy vấn con , để tránh đánh vần các phép tính cho mỗi hàng.
Thay thế public.tbl
(hai lần) bằng tên bảng tùy chọn lược đồ tùy chọn của bạn để có chế độ xem nhỏ gọn các thống kê được thu thập về kích thước của các hàng của bạn. Bạn có thể gói nó thành một hàm plpgsql để sử dụng nhiều lần, nhập tên bảng làm tham số và sử dụng EXECUTE
...
SELECT l.metric, l.nr AS "bytes/ct"
, CASE WHEN is_size THEN pg_size_pretty(nr) END AS bytes_pretty
, CASE WHEN is_size THEN nr / NULLIF(x.ct, 0) END AS bytes_per_row
FROM (
SELECT min(tableoid) AS tbl -- = 'public.tbl'::regclass::oid
, count(*) AS ct
, sum(length(t::text)) AS txt_len -- length in characters
FROM public.tbl t -- provide table name *once*
) x
, LATERAL (
VALUES
(true , 'core_relation_size' , pg_relation_size(tbl))
, (true , 'visibility_map' , pg_relation_size(tbl, 'vm'))
, (true , 'free_space_map' , pg_relation_size(tbl, 'fsm'))
, (true , 'table_size_incl_toast' , pg_table_size(tbl))
, (true , 'indexes_size' , pg_indexes_size(tbl))
, (true , 'total_size_incl_toast_and_indexes', pg_total_relation_size(tbl))
, (true , 'live_rows_in_text_representation' , txt_len)
, (false, '------------------------------' , NULL)
, (false, 'row_count' , ct)
, (false, 'live_tuples' , pg_stat_get_live_tuples(tbl))
, (false, 'dead_tuples' , pg_stat_get_dead_tuples(tbl))
) l(is_size, metric, nr);
Kết quả:
số liệu | byte / ct | byte_pretty | byte_per_row
----------------------------------- + ---------- + --- ----------- + ---------------
core_relation_size | 44138496 | 42 MB | 91
tầm nhìn_map | 0 | 0 byte | 0
free_space_map | 32768 | 32 kB | 0
bảng_size_incl_toast | 44179456 | 42 MB | 91
indexes_size | 33128448 | 32 MB | 68
Total_size_incl_toast_and_indexes | 77307904 | 74 MB | 159
live_rows_inSphere_Vpresentation | 29987360 | 29 MB | 62
------------------------------ | | |
hàng_count | 483424 | |
live_tuples | 483424 | |
dead_tuples | 2677 | |
Đối với phiên bản cũ hơn (Postgres 9.2 trở lên):
WITH x AS (
SELECT count(*) AS ct
, sum(length(t::text)) AS txt_len -- length in characters
, 'public.tbl'::regclass AS tbl -- provide table name as string
FROM public.tbl t -- provide table name as name
), y AS (
SELECT ARRAY [pg_relation_size(tbl)
, pg_relation_size(tbl, 'vm')
, pg_relation_size(tbl, 'fsm')
, pg_table_size(tbl)
, pg_indexes_size(tbl)
, pg_total_relation_size(tbl)
, txt_len
] AS val
, ARRAY ['core_relation_size'
, 'visibility_map'
, 'free_space_map'
, 'table_size_incl_toast'
, 'indexes_size'
, 'total_size_incl_toast_and_indexes'
, 'live_rows_in_text_representation'
] AS name
FROM x
)
SELECT unnest(name) AS metric
, unnest(val) AS "bytes/ct"
, pg_size_pretty(unnest(val)) AS bytes_pretty
, unnest(val) / NULLIF(ct, 0) AS bytes_per_row
FROM x, y
UNION ALL SELECT '------------------------------', NULL, NULL, NULL
UNION ALL SELECT 'row_count', ct, NULL, NULL FROM x
UNION ALL SELECT 'live_tuples', pg_stat_get_live_tuples(tbl), NULL, NULL FROM x
UNION ALL SELECT 'dead_tuples', pg_stat_get_dead_tuples(tbl), NULL, NULL FROM x;
Cùng một kết quả.
Q1: anything inefficient?
Bạn có thể tối ưu hóa thứ tự cột để lưu một số byte mỗi hàng, hiện đang lãng phí cho việc đệm căn chỉnh:
integer | not null default nextval('core_page_id_seq'::regclass)
integer | not null default 0
character varying(255) | not null
character varying(64) | not null
text | default '{}'::text
character varying(255) |
text | default '{}'::text
text |
timestamp with time zone |
timestamp with time zone |
integer |
integer |
Điều này tiết kiệm từ 8 đến 18 byte mỗi hàng. Tôi gọi nó là "cột tetris" . Chi tiết:
Cũng xem xét:
length(*)
hơn là chỉlength(field)
? Tôi biết đó là ký tự không phải byte nhưng tôi chỉ cần một giá trị xấp xỉ.