Hypopgは、仮想インデックスのサポートを追加する後の拡張拡張機能です。
仮説的(または仮想的なインデックスは、実際には存在しないインデックスであるため、CPU、ディスク、または作成するリソースがかかりません。 PostgreSQLがこれらのインデックスを使用してリソースを作成する必要があるかどうかを知ることができるため、特定のインデックスが問題のあるクエリのパフォーマンスを向上させることができるかどうかを知るのに役立ちます。
より徹底的な情報については、公式文書を参照してください。
他の一般情報については、このブログ投稿を参照することもできます。
sudo make installCREATE EXTENSION hypopg; 作成されたオブジェクトのいずれにも保存されているデータがないため、Hypopgは拡張アップグレードスクリプトを提供しないことに注意してください。したがって、最初に拡張機能をドロップしてから、新しいバージョンを取得するために再度作成する必要があります。
注:仮説インデックスは、単一のバックエンドに含まれています。したがって、複数の仮想インデックスを追加すると、 EXPLAINする同時接続が仮想インデックスに悩まされません。
簡単なテストケースを仮定してください:
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)
仮説インデックスを作成する最も簡単な方法は、argとして通常のCREATE INDEXステートメントを使用してhypopg_create_index関数を使用することです。
例えば:
rjuju=# SELECT * FROM hypopg_create_index('CREATE INDEX ON hypo (id)');
注: CREATE INDEX 、指定されている場合はインデックス名など、無視されます。無視された情報の一部は、将来のリリースで処理されます。
利用可能な仮想インデックスを独自のバックエンドで確認できます。
rjuju=# SELECT * FROM hypopg_list_indexes ;
indexrelid | index_name | schema_name | table_name | am_name
------------+-------------------------------+-------------+------------+---------
50573 | <50573>btree_hypo_id | public | hypo | btree
使用したいCREATE INDEXも引用する必要がある場合、1ドル引用符の構文を使用することをお勧めします。例えば:
rjuju=# SELECT * FROM hypopg_create_index($$CREATE INDEX ON hypo (id) WHERE val = 'line 1'$$);
仮説インデックスに関するより多くの技術情報が必要な場合、 hypopg()関数は、 pg_indexシステムカタログと同様の方法で仮説インデックスを返します。
そして今、あなたの以前のEXPLAINステートメントがそのようなインデックスを使用するかどうかを見てみましょう:
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)
もちろん、 ANALYZEなしでのみEXPLAINすると仮想インデックスを使用します。
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)
バックエンドの仮説インデックスを削除するには、 hypopg_list_indexesビューが返され、 hypopg_reset()を呼び出して一度に削除するか、現在の接続を閉じるoidを使用して、function hypopg_drop_index(indexrelid)を使用できます。
上記のケースを継続すると、 hide existing indexesできますが、最初は他のインデックスの以前の効果をクリアするには、 hypopg_reset()を使用する必要があります。
2つの実際のインデックスを作成し、 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)
クエリ計画では、 hypo_id_val_idxインデックスを使用しています。 hypopg_hide_index(oid)を使用して、インデックスの1つを非表示にします。
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)
クエリプランは、今すぐ他のインデックスhypo_id_idxを使用しています。 hypopg_hide_index(oid)を使用してそれを非表示にします。
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)
そして今、クエリ計画はSeq Scanに戻ります。 hypopg_unhide_index(oid)を使用してインデックスを復元します。
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)
もちろん、仮想インデックスを非表示にすることもできます。
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)
hypopg_hidden_indexes()または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)
既存のすべてのインデックスを復元するには、関数hypopg_unhide_all_indexes()を使用できます。既存のインデックスを非表示にする機能は、現在のセッションの説明コマンドにのみ適用され、他のセッションには影響しないことに注意してください。