帮你快速理解、总结文档立即下载

hypopg

最近更新时间:2026-09-16 11:44:01
我的收藏
本文为您介绍 hypopg 插件的简介及使用方法。

概述

hypopg 是虚拟索引评估插件,可在不实际创建索引的情况下模拟索引对查询计划的影响,用于评估索引收益、避免无效索引占用存储和拖慢写入。

支持版本

PostgreSQL 版本
内核版本
PostgreSQL 11
v11.22_r1.28及以上
PostgreSQL 12
v12.22_r1.31及以上
PostgreSQL 13
v13.22_r1.26及以上
PostgreSQL 14
v14.22_r1.42及以上
PostgreSQL 15
v15.14_r1.27及以上
PostgreSQL 16
v16.10_r1.22及以上
PostgreSQL 17
v17.9_r1.16及以上
PostgreSQL 18
v18.3_r1.6及以上
说明:
您可在控制台实例详情页查看当前实例的内核版本,或执行 SHOW tencentdb_version; 查询。

插件简介

hypopg 创建的虚拟索引只存在于当前会话中,不写入磁盘、不占用存储、不影响写入性能,仅对当前会话的 EXPLAIN(不含 ANALYZE)生效。通过对比创建虚拟索引前后的执行计划,可判断某索引是否值得真实创建。

环境准备

在目标数据库中执行以下语句创建扩展:
postgres=> CREATE EXTENSION hypopg;
CREATE EXTENSION
说明:
hypopg 无需预加载,创建后即可使用。

虚拟索引评估流程

1. 查看默认执行计划

以下示例创建测试表,并查看无索引时的执行计划:
postgres=> CREATE TABLE hypo_test(id int, val int);
CREATE TABLE
postgres=> INSERT INTO hypo_test SELECT i, i FROM generate_series(1, 10000) AS i;
INSERT 0 10000
postgres=> ANALYZE hypo_test;
ANALYZE
postgres=> EXPLAIN (COSTS OFF) SELECT * FROM hypo_test WHERE val = 5000;
QUERY PLAN
---------------------
Seq Scan on hypo_test
Filter: (val = 5000)
(2 rows)
无索引时,查询走全表扫描(Seq Scan)。

2. 创建虚拟索引

使用 hypopg_create_index 函数创建虚拟索引,参数为一条 CREATE INDEX 语句:
postgres=> SELECT * FROM hypopg_create_index('CREATE INDEX ON hypo_test (val)');
indexrelid | indexname
------------+---------------------------
12821 | <12821>btree_hypo_test_val
(1 row)
返回虚拟索引的 OID 和名称(名称由系统生成)。

3. 查看执行计划变化

再次执行 EXPLAIN,观察虚拟索引对计划的影响:
postgres=> EXPLAIN (COSTS OFF) SELECT * FROM hypo_test WHERE val = 5000;
QUERY PLAN
-----------------------------------------------------------
Index Scan using "<12821>btree_hypo_test_val" on hypo_test
Index Cond: (val = 5000)
(2 rows)
执行计划由全表扫描变为索引扫描,说明该索引对查询有效,值得真实创建。

4. 验证虚拟索引不占真实存储

postgres=> SELECT count(*) AS real_indexes FROM pg_indexes WHERE tablename = 'hypo_test';
real_indexes
--------------
0
(1 row)
系统目录中没有任何真实索引,虚拟索引不占用存储。

管理虚拟索引

查看虚拟索引列表

postgres=> SELECT * FROM hypopg_list_indexes;
indexrelid | index_name | schema_name | table_name | am_name
------------+---------------------------+-------------+------------+---------
12821 | <12821>btree_hypo_test_val | public | hypo_test | btree
(1 row)

查看虚拟索引定义

postgres=> SELECT hypopg_get_indexdef(indexrelid) FROM hypopg_list_indexes;
hypopg_get_indexdef
---------------------------------------------
CREATE INDEX ON public.hypo_test USING btree (val)
(1 row)

删除单个虚拟索引

postgres=> SELECT hypopg_drop_index((SELECT indexrelid FROM hypopg_list_indexes LIMIT 1));
hypopg_drop_index
-------------------
t
(1 row)

清空全部虚拟索引

postgres=> SELECT hypopg_reset();
hypopg_reset
--------------

(1 row)

参数说明

参数
默认值
说明
hypopg.enabled
on
是否启用 hypopg,设为 off 后虚拟索引不再影响 EXPLAIN
hypopg.use_real_oids
off
是否使用真实 OID(默认使用伪 OID 区间,备库也可使用)

常见问题

Q:虚拟索引会影响其他会话或真实数据吗?

A:不会。虚拟索引仅存在于创建它的会话中,断开连接即自动消失,不写入磁盘、不影响其他会话和写入性能。

Q:为什么 EXPLAIN ANALYZE 看不到虚拟索引的效果?

A:虚拟索引仅对 EXPLAIN(不含 ANALYZE)生效。EXPLAIN ANALYZE 会真实执行查询,无法使用不存在的虚拟索引。

Q:如何验证多个候选索引?

A:可在同一会话中多次调用 hypopg_create_index 创建多个虚拟索引,用 hypopg_list_indexes 查看列表,配合 EXPLAIN 逐一或组合评估,评估完成后用 hypopg_reset 清空。

相关参考