Hypopg es una extensión PostgreSQL que agrega soporte para índices hipotéticos.
Un índice hipotético, o virtual, es un índice que realmente no existe y, por lo tanto, no cuesta CPU, disco o ningún recurso para crear. Son útiles para saber si los índices específicos pueden aumentar el rendimiento de consultas problemáticas, ya que puede saber si PostgreSQL usará estos índices o no sin tener que gastar recursos para crearlos.
Para obtener información más exhaustiva, consulte la documentación oficial.
Para otra información general, también puede consultar esta publicación de blog.
sudo make installCREATE EXTENSION hypopg; Tenga en cuenta que Hypopg no proporciona scripts de actualización de extensión, ya que no hay datos guardados en ninguno de los objetos creados. Por lo tanto, primero debe soltar la extensión y luego volver a crearla para obtener la nueva versión.
Nota: Los índices hipotéticos están contenidos en un solo backend. Por lo tanto, si agrega múltiples índices hipotéticos, las conexiones concurrentes que hacen EXPLAIN no se molestarán por sus índices hipotéticos.
Suponiendo un caso de prueba simple:
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)
La forma más fácil de crear un índice hipotético es usar las funciones hypopg_create_index con una declaración CREATE INDEX regular como Arg.
Por ejemplo:
rjuju=# SELECT * FROM hypopg_create_index('CREATE INDEX ON hypo (id)');
Nota: Se ignorará alguna información de la declaración CREATE INDEX , como el nombre del índice si se proporciona. Parte de la información ignorada se manejará en una versión futura.
Puede verificar los índices hipotéticos disponibles en su propio backend:
rjuju=# SELECT * FROM hypopg_list_indexes ;
indexrelid | index_name | schema_name | table_name | am_name
------------+-------------------------------+-------------+------------+---------
50573 | <50573>btree_hypo_id | public | hypo | btree
Si el comando CREATE INDEX que desea usar también necesita citar, se recomienda usar la sintaxis de cotización en dólares. Por ejemplo:
rjuju=# SELECT * FROM hypopg_create_index($$CREATE INDEX ON hypo (id) WHERE val = 'line 1'$$);
Si necesita más información técnica sobre los índices hipotéticos, la función hypopg() devolverá los índices hipotéticos de manera similar al catálogo del sistema pg_index .
Y ahora, veamos si su declaración EXPLAIN anterior usaría dicho índice:
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)
Por supuesto, solo EXPLAIN sin ANALYZE utilizará índices hipotéticos:
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)
Para eliminar los índices hipotéticos de su backend, puede usar la función hypopg_drop_index(indexrelid) con la OID que la vista hypopg_list_indexes regresa y llame hypopg_reset() para eliminar todo a la vez, o simplemente cierre su conexión actual.
Continuando con el caso anterior, puede hide existing indexes , pero debe usarse hypopg_reset() para borrar los efectos anteriores de otros índices al principio.
Crear dos índices reales y ejecutar 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)
El plan de consulta está utilizando el índice hypo_id_val_idx . Use hypopg_hide_index(oid) para ocultar uno de los índices:
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)
El plan de consulta está utilizando el otro índice hypo_id_idx ahora. Use hypopg_hide_index(oid) para ocultarlo:
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)
Y ahora el plan de consulta cambia a Seq Scan . Use hypopg_unhide_index(oid) para restaurar el índice:
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)
Por supuesto, también puede ocultar índices hipotéticos:
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)
Puede verificar qué índices están ocultos utilizando hypopg_hidden_indexes() o la vista 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)
Para restaurar todos los índices existentes, puede usar la función hypopg_unhide_all_indexes() . Tenga en cuenta que la funcionalidad para ocultar los índices existentes solo se aplica al comando Explicar en la sesión actual y no afectará otras sesiones.