BTree
Masalah saya di sini adalah bahwa indeks BTree akan sangat besar karena afaict akan menyimpan nilai duplikat (juga, karena tidak dapat menganggap tabel diurutkan secara fisik). Jika BTree besar saya akhirnya harus membaca indeks dan bagian-bagian tabel yang indeksnya juga ...
Belum tentu - Memiliki indeks btree yang 'meliputi' akan menjadi waktu membaca tercepat, dan jika hanya itu yang Anda inginkan (yaitu jika Anda mampu membeli penyimpanan tambahan), maka itu adalah taruhan terbaik Anda.
BRIN
Pemahaman saya adalah bahwa saya dapat memiliki indeks kecil di sini dengan mengorbankan membaca halaman yang tidak berguna. Menggunakan yang kecil pages_per_range
berarti bahwa indeksnya lebih besar (yang merupakan masalah dengan BRIN karena saya perlu membaca keseluruhan indeks), memiliki pages_per_range
sarana yang besar sehingga saya akan membaca banyak halaman yang tidak berguna.
Jika Anda tidak mampu membeli overhead penyimpanan dari indeks btree penutup, BRIN sangat ideal untuk Anda, karena Anda sudah memiliki pengelompokan (ini sangat penting bagi BRIN untuk berguna). Indeks BRIN kecil , sehingga semua halaman cenderung berada dalam memori jika Anda memilih nilai yang sesuai pages_per_range
.
Apakah ada rumus ajaib untuk menemukan nilai pages_per_range yang bagus yang memperhitungkan pertukaran tersebut?
Tidak ada rumus ajaib, tetapi mulai dengan pages_per_range
sedikit kurang dari ukuran rata-rata (dalam halaman) yang ditempati oleh nilai rata-rata a
. Anda mungkin mencoba memperkecil: (jumlah halaman BRIN dipindai) + (jumlah halaman tumpukan yang dipindai) untuk kueri yang khas. Cari Heap Blocks: lossy=n
dalam rencana eksekusi pages_per_range=1
dan bandingkan dengan nilai-nilai lain untuk pages_per_range
- yaitu melihat berapa banyak heap block yang tidak perlu sedang dipindai.
GIN / GiST
Tidak yakin itu relevan di sini karena sebagian besar digunakan untuk pencarian teks lengkap, tetapi saya juga mendengar bahwa mereka pandai menangani kunci duplikat. Apakah salah satu GIN
/ GiST
indeks membantu di sini?
GIN mungkin layak dipertimbangkan, tetapi mungkin bukan GST - namun jika pengelompokan alami benar-benar baik, maka BRIN mungkin akan menjadi taruhan yang lebih baik.
Berikut ini adalah perbandingan sampel antara berbagai jenis indeks untuk data tiruan sedikit seperti milik Anda:
tabel dan indeks:
create table foo(a,b,c) as
select *, lpad('',20)
from (select chr(g) a from generate_series(97,122) g) a
cross join (select generate_series(1,100000) b) b
order by a;
create index foo_btree_covering on foo(a,b);
create index foo_btree on foo(a);
create index foo_gin on foo using gin(a);
create index foo_brin_2 on foo using brin(a) with (pages_per_range=2);
create index foo_brin_4 on foo using brin(a) with (pages_per_range=4);
vacuum analyze;
ukuran hubungan:
select relname "name", pg_size_pretty(siz) "size", siz/8192 pages, (select count(*) from foo)*8192/siz "rows/page"
from( select relname, pg_relation_size(C.oid) siz
from pg_class c join pg_namespace n on n.oid = c.relnamespace
where nspname = current_schema ) z;
nama | ukuran | halaman | baris / halaman
: ----------------- | : ------ | ----: | --------:
foo | 149 MB | 19118 | 135
foo_btree_covering | 56 MB | 7132 | 364
foo_btree | 56 MB | 7132 | 364
foo_gin | 2928 kB | 366 | 7103
foo_brin_2 | 264 kB | 33 | 78787
foo_brin_4 | 136 kB | 17 | 152941
meliputi btree:
explain analyze select sum(b) from foo where a='a';
| RENCANA QUERY |
| : ------------------------------------------------- -------------------------------------------------- ------------------------------------------- |
| Agregat (biaya = 3282.57..3282.58 baris = 1 lebar = 8) (waktu aktual = 45.942..45.942 baris = 1 loop = 1) |
| -> Indeks Hanya Memindai menggunakan foo_btree_covering on foo (biaya = 0,43..3017,80 baris = lebar 105907 = 4) (waktu aktual = 0,038..27.286 baris = 100000 putaran = 1) |
| Indeks Cond: (a = 'a' :: text) |
| Heap Fetches: 0 |
| Waktu perencanaan: 0,099 ms |
| Waktu pelaksanaan: 45.968 ms |
btree polos:
drop index foo_btree_covering;
explain analyze select sum(b) from foo where a='a';
| RENCANA QUERY |
| : ------------------------------------------------- -------------------------------------------------- ----------------------------- |
| Agregat (biaya = 4064,57..4064.58 baris = 1 lebar = 8) (waktu aktual = 54.242..54.242 baris = 1 loop = 1) |
| -> Pemindaian Indeks menggunakan foo_btree on foo (biaya = 0,43..3799,80 baris = lebar 105907 = 4) (waktu aktual = 0,037..33.084 baris = 100000 putaran = 1) |
| Indeks Cond: (a = 'a' :: text) |
| Waktu perencanaan: 0.135 ms |
| Waktu pelaksanaan: 54.280 ms |
BRIN pages_per_range = 4:
drop index foo_btree;
explain analyze select sum(b) from foo where a='a';
| RENCANA QUERY |
| : ------------------------------------------------- -------------------------------------------------- ----------------------------- |
| Agregat (biaya = 21595.38..21595.39 baris = 1 lebar = 8) (waktu aktual = 52.455..52.455 baris = 1 loop = 1) |
| -> Bitmap Heap Scan pada foo (biaya = 888.78..21330.61 baris = lebar 105907 = 4) (waktu aktual = 2.738..31.967 baris = 100000 putaran = 1) |
| Periksa kembali Cond: (a = 'a' :: text) |
| Baris Dihapus oleh Indeks Periksa kembali: 96 |
| Heap Blocks: lossy = 736 |
| -> Indeks Bitmap Memindai pada foo_brin_4 (biaya = 0,00..862,30 baris = lebar 105907 = 0) (waktu aktual = 2,720..2,720 baris = 7360 loop = 1) |
| Indeks Cond: (a = 'a' :: text) |
| Waktu perencanaan: 0,101 ms |
| Waktu pelaksanaan: 52.501 ms |
BRIN pages_per_range = 2:
drop index foo_brin_4;
explain analyze select sum(b) from foo where a='a';
| RENCANA QUERY |
| : ------------------------------------------------- -------------------------------------------------- ----------------------------- |
| Agregat (biaya = 21659,38..21659,39 baris = 1 lebar = 8) (waktu aktual = 53.971..53.971 baris = 1 loop = 1) |
| -> Bitmap Heap Scan pada foo (biaya = 952,78..21394.61 baris = lebar 105907 = 4) (waktu aktual = 5.286..33.492 baris = 100000 putaran = 1) |
| Periksa kembali Cond: (a = 'a' :: text) |
| Baris Dihapus oleh Indeks Periksa kembali: 96 |
| Heap Blocks: lossy = 736 |
| -> Indeks Bitmap Memindai pada foo_brin_2 (biaya = 0,00..926,30 baris = lebar 105907 = 0) (waktu aktual = 5,275.,5.275 baris = 7360 loop = 1) |
| Indeks Cond: (a = 'a' :: text) |
| Waktu perencanaan: 0,095 ms |
| Waktu pelaksanaan: 54.016 ms |
GIN:
drop index foo_brin_2;
explain analyze select sum(b) from foo where a='a';
| RENCANA QUERY |
| : ------------------------------------------------- -------------------------------------------------- ------------------------------ |
| Agregat (biaya = 21687.38..21687.39 baris = 1 lebar = 8) (waktu aktual = 55.331..55.331 baris = 1 putaran = 1) |
| -> Bitmap Heap Scan pada foo (biaya = 980.78..21422.61 baris = lebar 105907 = 4) (waktu aktual = 12.377..33.956 baris = 100000 putaran = 1) |
| Periksa kembali Cond: (a = 'a' :: text) |
| Heap Blocks: tepat = 736 |
| -> Pemindaian Indeks Bitmap pada foo_gin (biaya = 0,00..954,30 baris = lebar 105907 = 0) (waktu aktual = 12,271..12,271 baris = 100000 loop = 1) |
| Indeks Cond: (a = 'a' :: text) |
| Waktu perencanaan: 0.118 ms |
| Waktu pelaksanaan: 55.366 ms |
Aku di sini