Hypopg - это расширение PostgreSQL, добавляя поддержку гипотетических индексов.
Гипотетический - или виртуальный индекс - это индекс, который на самом деле не существует, и, следовательно, не стоит ЦП, диск или какой -либо ресурс для создания. Они полезны, чтобы знать, могут ли конкретные индексы повысить производительность для проблемных запросов, поскольку вы можете знать, будет ли 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)
Самый простой способ создания гипотетического индекса - это использовать функции hypopg_create_index с регулярным оператором CREATE INDEX как Arg.
Например:
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 которую вы хотите использовать, также нуждается в цитате, рекомендуется использовать синтаксис цитирования в долларах. Например:
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)
Конечно, EXPLAIN только без ANALYZE будет использовать гипотетические индексы:
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_drop_index(indexrelid) с OID, который возвращает представление hypopg_list_indexes и вызовать hypopg_reset() , чтобы удалить все сразу или просто закрыть ваше текущее соединение.
Продолжая с приведенным выше случаем, вы можете hide existing indexes , но следует использовать hypopg_reset() чтобы сначала очистить предыдущие эффекты других индексов.
Создайте два реальных индекса и запустите, 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) , чтобы скрыть один из индексов:
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() . Обратите внимание, что функциональность, чтобы скрыть существующие индексы, применяется только к команде объяснения в текущем сеансе и не будет влиять на другие сеансы.