Hipopg adalah ekstensi PostgreSQL yang menambahkan dukungan untuk indeks hipotetis.
Indeks hipotetis - atau virtual - adalah indeks yang tidak benar -benar ada, dan dengan demikian tidak memerlukan biaya CPU, disk, atau sumber daya apa pun untuk dibuat. Mereka berguna untuk mengetahui apakah indeks spesifik dapat meningkatkan kinerja untuk kueri yang bermasalah, karena Anda dapat mengetahui apakah PostgreSQL akan menggunakan indeks ini atau tidak tanpa harus menghabiskan sumber daya untuk membuatnya.
Untuk informasi lebih lanjut, silakan berkonsultasi dengan dokumentasi resmi.
Untuk informasi umum lainnya, Anda juga dapat berkonsultasi dengan posting blog ini.
sudo make installCREATE EXTENSION hypopg; Perhatikan bahwa hipopg tidak menyediakan skrip peningkatan ekstensi, karena tidak ada data yang disimpan di salah satu objek yang dibuat. Karena itu, Anda harus terlebih dahulu menjatuhkan ekstensi kemudian membuatnya lagi untuk mendapatkan versi baru.
Catatan: Indeks hipotetis terkandung dalam satu backend tunggal. Oleh karena itu, jika Anda menambahkan beberapa indeks hipotetis, koneksi bersamaan yang dilakukan EXPLAIN tidak akan diganggu oleh indeks hipotetis Anda.
Dengan asumsi kasus uji sederhana:
rjuju=# CREATE TABLE hypo AS SELECT id, 'line ' || id AS val FROM generate_series(1,10000) id;
rjuju=# EXPLAIN SELECT * FROM hypo WHERE id = 1;
QUERY PLAN
-------------------------------------------------------
Seq Scan on hypo (cost=0.00..180.00 rows=1 width=13)
Filter: (id = 1)
(2 rows)
Cara termudah untuk membuat indeks hipotetis adalah dengan menggunakan fungsi hypopg_create_index dengan pernyataan CREATE INDEX reguler sebagai arg.
Misalnya:
rjuju=# SELECT * FROM hypopg_create_index('CREATE INDEX ON hypo (id)');
Catatan: Beberapa informasi dari pernyataan CREATE INDEX akan diabaikan, seperti nama indeks jika disediakan. Beberapa informasi yang diabaikan akan ditangani dalam rilis di masa mendatang.
Anda dapat memeriksa indeks hipotetis yang tersedia di backend Anda sendiri:
rjuju=# SELECT * FROM hypopg_list_indexes ;
indexrelid | index_name | schema_name | table_name | am_name
------------+-------------------------------+-------------+------------+---------
50573 | <50573>btree_hypo_id | public | hypo | btree
Jika perintah CREATE INDEX yang ingin Anda gunakan juga perlu dikutip, menggunakan Sintaks Dollar Quoting disarankan. Misalnya:
rjuju=# SELECT * FROM hypopg_create_index($$CREATE INDEX ON hypo (id) WHERE val = 'line 1'$$);
Jika Anda memerlukan lebih banyak informasi teknis tentang indeks hipotetis, fungsi hypopg() akan mengembalikan indeks hipotetis dengan cara yang sama seperti katalog sistem pg_index .
Dan sekarang, mari kita lihat apakah pernyataan EXPLAIN Anda sebelumnya akan menggunakan indeks seperti itu:
rjuju=# EXPLAIN SELECT * FROM hypo WHERE id = 1;
QUERY PLAN
------------------------------------------------------------------------------------
Index Scan using <41072>hypo_btree_hypo_id on hypo (cost=0.29..8.30 rows=1 width=13)
Index Cond: (id = 1)
(2 rows)
Tentu saja, hanya EXPLAIN tanpa ANALYZE akan menggunakan indeks hipotetis:
rjuju=# EXPLAIN ANALYZE SELECT * FROM hypo WHERE id = 1;
QUERY PLAN
-------------------------------------------------------------------------------------------------
Seq Scan on hypo (cost=0.00..180.00 rows=1 width=13) (actual time=0.036..6.072 rows=1 loops=1)
Filter: (id = 1)
Rows Removed by Filter: 9999
Planning time: 0.109 ms
Execution time: 6.113 ms
(5 rows)
Untuk menghapus indeks hipotetis backend Anda, Anda dapat menggunakan fungsi hypopg_drop_index(indexrelid) dengan OID yang dihapus oleh hypopg_list_indexes dan hubungi hypopg_reset() untuk menghapus sekaligus, atau cukup tutup koneksi Anda saat ini.
Melanjutkan dengan kasus di atas, Anda dapat hide existing indexes , tetapi harus menggunakan hypopg_reset() untuk menghapus efek sebelumnya dari indeks lain pada awalnya.
Buat dua indeks nyata dan jalankan EXPLAIN :
rjuju=# SELECT hypopg_reset();
rjuju=# CREATE INDEX ON hypo(id);
rjuju=# CREATE INDEX ON hypo(id, val);
rjuju=# EXPLAIN SELECT * FROM hypo WHERE id = 1;
QUERY PLAN
----------------------------------------------------------------------------------
Index Only Scan using hypo_id_val_idx on hypo (cost=0.29..8.30 rows=1 width=13)
Index Cond: (id = 1)
(2 rows)
Rencana kueri menggunakan indeks hypo_id_val_idx . Gunakan hypopg_hide_index(oid) untuk menyembunyikan salah satu indeks:
rjuju=# SELECT hypopg_hide_index('hypo_id_val_idx'::REGCLASS);
rjuju=# EXPLAIN SELECT * FROM hypo WHERE id = 1;
QUERY PLAN
-------------------------------------------------------------------------
Index Scan using hypo_id_idx on hypo (cost=0.29..8.30 rows=1 width=13)
Index Cond: (id = 1)
(2 rows)
Rencana kueri menggunakan indeks lain hypo_id_idx sekarang. Gunakan hypopg_hide_index(oid) untuk menyembunyikannya:
rjuju=# SELECT hypopg_hide_index('hypo_id_idx'::REGCLASS);
rjuju=# EXPLAIN SELECT * FROM hypo WHERE id = 1;
QUERY PLAN
-------------------------------------------------------
Seq Scan on hypo (cost=0.00..180.00 rows=1 width=13)
Filter: (id = 1)
(2 rows)
Dan sekarang rencana kueri berubah kembali ke Seq Scan . Gunakan hypopg_unhide_index(oid) untuk memulihkan indeks:
rjuju=# SELECT hypopg_unhide_index('hypo_id_idx'::regclass);
rjuju=# EXPLAIN SELECT * FROM hypo WHERE id = 1;
QUERY PLAN
-------------------------------------------------------------------------
Index Scan using hypo_id_idx on hypo (cost=0.29..8.30 rows=1 width=13)
Index Cond: (id = 1)
(2 rows)
Tentu saja, Anda juga dapat menyembunyikan indeks hipotetis:
rjuju=# SELECT hypopg_create_index('CREATE INDEX ON hypo(id)');
rjuju=# EXPLAIN SELECT * FROM hypo WHERE id = 1;
QUERY PLAN
------------------------------------------------------------------------------------
Index Scan using "<12659>btree_hypo_id" on hypo (cost=0.04..8.05 rows=1 width=13)
Index Cond: (id = 1)
(2 rows)
rjuju=# SELECT hypopg_hide_index(12659);
rjuju=# EXPLAIN SELECT * FROM hypo WHERE id = 1;
QUERY PLAN
-------------------------------------------------------
Seq Scan on hypo (cost=0.00..180.00 rows=1 width=13)
Filter: (id = 1)
(2 rows)
Anda dapat memeriksa indeks mana yang disembunyikan menggunakan hypopg_hidden_indexes() atau tampilan hypopg_hidden_indexes :
rjuju=# SELECT * FROM hypopg_hidden_indexes();
indexid
---------
526604
526603
12659
(3 rows)
rjuju=# SELECT * FROM hypopg_hidden_indexes;
indexrelid | index_name | schema_name | table_name | am_name | is_hypo
------------+----------------------+-------------+------------+---------+---------
12659 | <12659>btree_hypo_id | public | hypo | btree | t
526603 | hypo_id_idx | public | hypo | btree | f
526604 | hypo_id_val_idx | public | hypo | btree | f
(3 rows)
Untuk mengembalikan semua indeks yang ada, Anda dapat menggunakan fungsi hypopg_unhide_all_indexes() . Perhatikan bahwa fungsionalitas untuk menyembunyikan indeks yang ada hanya berlaku untuk perintah menjelaskan dalam sesi saat ini dan tidak akan mempengaruhi sesi lain.