Q2: way to measure page size
PostgreSQL menyediakan sejumlah Fungsi Ukuran Objek Basis Data . Saya mengemas yang paling menarik dalam kueri ini dan menambahkan beberapa Fungsi Akses Statistik di bagian bawah. (Modul pgstattuple tambahan menyediakan fungsi yang lebih bermanfaat.)
Ini akan menunjukkan bahwa metode yang berbeda untuk mengukur "ukuran baris" mengarah ke hasil yang sangat berbeda. Itu semua tergantung pada apa yang ingin Anda ukur, tepatnya.
Permintaan ini membutuhkan Postgres 9.3 atau lebih baru . Untuk versi yang lebih lama lihat di bawah.
Menggunakan VALUES
ekspresi dalam LATERAL
subquery , untuk menghindari mengeja perhitungan untuk setiap baris.
Ganti public.tbl
(dua kali) dengan nama tabel yang memenuhi syarat untuk skema Anda untuk mendapatkan tampilan yang kompak dari statistik yang dikumpulkan tentang ukuran baris Anda. Anda bisa membungkus ini menjadi fungsi plpgsql untuk penggunaan berulang, masukkan nama tabel sebagai parameter dan gunakan 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);
Hasil:
metrik | byte / ct | bytes_pretty | bytes_per_row
----------------------------------- + ---------- + --- ----------- + ---------------
core_relation_size | 44138496 | 42 MB | 91
visibility_map | 0 | 0 byte | 0
free_space_map | 32768 | 32 kB | 0
table_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_in_text_representation | 29987360 | 29 MB | 62
------------------------------ | | |
row_count | 483424 | |
live_tuples | 483424 | |
dead_tuples | 2677 | |
Untuk versi yang lebih lama (Postgres 9.2 atau lebih lama):
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;
Hasil yang sama
Q1: anything inefficient?
Anda dapat mengoptimalkan pesanan kolom untuk menghemat beberapa byte per baris, yang saat ini terbuang untuk pelurusan pelurusan:
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 |
Ini menghemat antara 8 dan 18 byte per baris. Saya menyebutnya "kolom tetris" . Detail:
Juga pertimbangkan:
length(*)
bukan hanyalength(field)
? Saya tahu itu bukan byte byte tetapi saya hanya perlu nilai sekitar.