Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >PostgreSQL插件HypoPG:支持虚拟索引

PostgreSQL插件HypoPG:支持虚拟索引

作者头像
yzsDBA
发布于 2023-09-07 01:27:03
发布于 2023-09-07 01:27:03
32900
代码可运行
举报
运行总次数:0
代码可运行

通过索引可以加速查询。但是执行SQL时,并不是所有索引都会使用。如果花费很长时间创建一个索引,最后却用不到,岂不是又浪费时间又浪费磁盘空间。那有没有啥方法,可以即不浪费时间又不浪费空间,提前知道这个索引能否可用?HypoPG插件可以帮助创建一个虚拟索引,即不耗费CPU也不耗费磁盘

轻量级实现:HypoPG

HypoPG作为扩展插件,可拔插,支持PG9.2及其以上版本,无需重新启动服务即可使用。每个后端都有自己的一组虚拟索引,并不会干扰其他连接。另外,虚拟索引存储在内存中,添加/删除大量索引并不会使系统目录膨胀。该插件实现的限制:必须通过用户自定义函数来完成。

使用方法

使用时,需要CREATE EXTENSION hypopg;来加载插件。

虚拟索引属于独立后台进程,因此并发时,不同进程的虚拟索引并不会彼此影响。下面是也给例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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语句作为参数的函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rjuju=# SELECT * FROM hypopg_create_index('CREATE INDEX ON hypo (id)');

注意,CREATE INDEX语句中某些信息会被忽略,例如索引名。一些被忽略的信息会在未来版本中处理。

也可以在自己的后端查看可用的虚拟索引:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rjuju=# SELECT * FROM hypopg_list_indexes ;
indexrelid |                 indexname                 | nspname | relname | amname
-----------+-------------------------------------------+---------+---------+--------
205101     | <41072>btree_hypo_id                      | public  | hypo    | btree

如果需要有关虚拟索引更多信息,hypopg()函数将以类似于pg_index系统目录的方式返回虚拟索引。限制看下之前的EXPLAIN语句是否会使用这样的索引:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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后就不会使用了

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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)函数将虚拟索引删除,或者关闭当前连接。

该插件还提供了隐藏和恢复某个索引的功能:

1)先用hypopg_reset()清除其他索引之前的影响:SELECT hypopg_reset();

2)创建2个虚拟索引,并执行EXPLAIN

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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)

3)查询计划使用hypo_id_val_idx索引,使用hypopg_hide_index(oid)隐藏其中一个索引:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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)

4)查询计划使用了另一个索引hypo_id_idx。使用hypopg_hide_index(oid)再把它隐藏掉:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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)

查询计划又退回使用SeqScan了。

5)使用hypopg_unhide_index(oid)恢复索引:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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)

6)可以使用函数hypopg_hidden_indexes()或者视图hypopg_hidden_indexes查看隐藏了哪些索引:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rjuju=# SELECT * FROM hypopg_hidden_indexes();
indexid
---------
526604
526603
12659
(3 rows)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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)

7)可以使用函数hypopg_unhide_all_indexes()恢复所有隐藏的虚拟索引。请注意,隐藏现有索引的功能仅适用于当前会话中的 EXPLAIN 命令,不会影响其他会话。

参考

https://rjuju.github.io/postgresql/2015/07/02/how-about-hypothetical-indexes.html

https://github.com/HypoPG/hypopg

https://hypopg.readthedocs.io/en/rel1_stable/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-06-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 yanzongshuaiDBA 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
进阶数据库系列(十二):PostgreSQL 索引技术详解
索引主要被用来提升数据库性能,不当的使用会导致性能变差。 PostgreSQL 提供了多种索引类型: B-tree、Hash、GiST、SP-GiST 、GIN 和 BRIN。每一种索引类型使用了一种不同的算法来适应不同类型的查询。默认情况下,CREATE INDEX 命令创建适合于大部分情况的 B-tree 索引。
民工哥
2023/08/22
3.3K0
进阶数据库系列(十二):PostgreSQL 索引技术详解
PG几个有趣的插件和工具介绍
PGTune可以根据给定硬件配置的最大性能计算PostgreSQL配置。对于初学者来说可以快速地来配置数据库参数。但它不是PostgreSQL优化设置的灵丹妙药。许多设置不仅取决于硬件配置,还取决于数据库的大小、客户端的数量和查询的复杂性。只有考虑到所有这些参数,才能对数据库进行最佳配置。
AiDBA宝典
2023/09/19
1K0
PG几个有趣的插件和工具介绍
PostgreSQL的B-tree索引
B-tree索引适合用于存储排序的数据。对于这种数据类型需要定义大于、大于等于、小于、小于等于操作符。
yzsDBA
2020/10/29
4.8K0
PostgreSQL的B-tree索引
PostgreSQL 性能优化创建正确的索引具有不确定性
索引在数据库的查询中起到的作用毋庸置疑,但时常有人提出索引的建立的问题,to be or not to be 的问题。
AustinDatabases
2022/05/19
1K0
PostgreSQL  性能优化创建正确的索引具有不确定性
使用pg_hint_plan固定Postgresql执行计划
pg_hint_plan的使用教程很多,本篇主要通过实例介绍一些使用时经常遇到的问题,例如:
mingjie
2023/10/13
1.4K0
布隆过滤器在PostgreSQL中的应用
作为学院派的数据库,postgresql在底层的架构设计上就考虑了很多算法层面的优化。其中在postgresql9.6版本中推出bloom索引也是十足的黑科技。
数据库架构之美
2021/04/07
2.7K0
布隆过滤器在PostgreSQL中的应用
Postgresql 损坏的索引怎么查出来,解决了他
POSTGRESQL 中如果你的表文件有损坏,则在查询中会直接告诉你某些文件缺失,你无法对这个表进行查询,或操作. 如果是索引可能就没有这么的简单了.
AustinDatabases
2021/04/01
1.1K0
Postgresql排序与limit组合场景性能极限优化
测试场景的限制GIN索引查询速度是很快的, 在实际生产中,可能出现使用gin索引后,查询速度依然很高的情况,特点就是执行计划中Bitmap Heap Scan占用了大量时间,Bitmap Index Scan大部分标记的块都被过滤掉了。
mingjie
2022/05/12
7260
PostgreSQL中索引是否存储空值?
偶然在PostgreSQL官方文档上看到这句话:an IS NULL or IS NOT NULL condition on an index column can be used with a B-Tree index。
数据库架构之美
2021/03/16
2.7K0
Postgresql分区表大量实例与分区建议(LIST / RANGE / HASH / 多级混合分区)
5.11.6. Best Practices for Declarative Partitioning
mingjie
2022/09/26
7.3K0
从Oracle到PostgreSQL:Storage Index 特性 vs BRIN索引
导读:本文介绍 PostgreSQL 中的BRIN索引。为什么引人注意专门单独讲述这个性能?因为这就是活脱脱的 Oracle Exadata 中的 Storage Index 和 Oracle Database 12.1.0.2 中的新功能 Zone Maps。
数据和云01
2019/06/19
5360
PostgreSQL技术大讲堂 - 第29讲:执行计划与成本估算
PostgreSQL从小白到专家,是从入门逐渐能力提升的一个系列教程,内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容,希望对热爱PG、学习PG的同学们有帮助,欢迎持续关注CUUG PG技术大讲堂。
用户5892232
2023/09/14
9120
PostgreSQL技术大讲堂 - 第29讲:执行计划与成本估算
Postgresql INDEX HOT 原理与更好的 “玩转” INDEX
好长时间不进行研究了,最近被突发的问题想到了INDEX 的问题,随机想到数据和INDEX 存储在一起会怎样,我们将索引和数据进行分离后,会不会对数据库的性能有优化的可能。
AustinDatabases
2023/02/26
1.2K0
Postgresql  INDEX  HOT 原理与更好的 “玩转”  INDEX
PostgreSQL 如何对索引进行分析和处理
最近有人私信问POSTGRESQL 怎么比MYSQL的索引大,这个问题升级上我个人觉得从这几点考虑
AustinDatabases
2023/09/06
3880
PostgreSQL 如何对索引进行分析和处理
Clustering a Table - Bruce Momjian(译)
写了600 多篇博客文章后,我以为我已经掌握了cluster命令的复杂性 ,但似乎我还没有,所以现在让我们开始吧。
数据库架构之美
2021/08/06
9120
PostgreSQL给模糊搜索加索引 转
PostgrSQL有个模块叫pg_trgm,可以对字符串来进行比较相似度,并通过加GIST或者GIN索引来达到提速的效果。在一般的RDBMS中这种需求都会进行全表扫描的,但是PG如果加了这个模块,在一定场景下就可以使用索引来提速了。 一、背景 我们有一个需求根据人员的拼音码(或者药品的拼音码)进行搜索,因为拼音码不一定是全的,故通常给的方案是模糊搜索,在拼音码的首尾两端各加一个百分号,但是效率通常很慢,一般情况下也不建议这么做。 二、环境 OS:CentOS 6.5 DB:PostgreSQL 9.3 三、步骤 1.因为DB是通过源码编译的,所以创建很简单,只要添加一个扩展
双面人
2019/04/10
1.7K0
PostgreSQL JSONB 使用入门
Photo by Tobias Fischer[9] on Unsplash[10]
goodspeed
2020/12/22
8.5K0
PostgreSQL JSONB 使用入门
PostgreSQL学术之美-从数据相关性看索引扫描IO放大问题
PostgreSQL是学术派的数据库,这体现在它架构设计的方方面面,例如多表连接动态规划、改进的内存置换时钟扫描算法、空间索引等,PG甚至将优化器的各类代价因子放开成参数供我们调整,这真是很开放的举动。
数据库架构之美
2020/11/19
7720
PostgreSQL学术之美-从数据相关性看索引扫描IO放大问题
索引与PostgreSQL新手
PostgreSQL 查询计划器充满了惊喜,因此编写高性能查询的常识性方法有时会产生误导。在这篇博文中,我将描述借助 EXPLAIN ANALYZE 和 Postgres 元数据分析优化看似显而易见的查询的示例。
PGCCC
2022/02/11
1.4K0
索引与PostgreSQL新手
PostgreSQL扫描方法综述
关系型数据库都需要产生一个最佳的执行计划从而在查询时耗费的时间和资源最少。通常情况下,所有的数据库都会产生一个以树形式的执行计划:计划树的叶子节点被称为表扫描节点。查询节点对应于从基表获取数据。
yzsDBA
2020/10/28
1.8K0
PostgreSQL扫描方法综述
推荐阅读
相关推荐
进阶数据库系列(十二):PostgreSQL 索引技术详解
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验