PostgreSQL 14新特性--减少索引膨胀
PG12中索引的存储更加高效,PG13添加索引条目去重功能进一步提升存储效率。PG14将带来“自底向上”的索引条目去除功能,旨在减少不必要的页面分裂、索引膨胀和更新大量索引带来的碎片。
为什么会出现索引膨胀
对于B-tree索引,表中每个行版本都有一个未死的索引条目(对所有人可见)。执行vacuum删除死记录时,也会删除对应的索引条目。和表一样,同样会在索引页中创建空的空间。这样的空间可以重用,但是如果没有新元组插入该页,这样的空间会保持为空。
这种膨胀在某种程度上是不可避免的,也是正常的。但如果膨胀太多,索引效率就会降低:
1) 对于索引范围扫描,必须扫描更多的页
2) RAM中缓存了索引页,意味着缓冲膨胀,就是浪费了RAM
3) 每个页中更少的索引条目意味着更少的“fan out”,索引树的层级将更高
如果频繁更新相同行,就会发生这种情况。VACUUM清理老元组前,表和索引会维护相同行的很多版本。如果索引页填满,将令人很烦:然后PG会将索引页分裂成2个。这是一个昂贵的操作,VACUUM执行完清理,我们最终会得到2个臃肿的页面而不是一个。
当前用于改善索引膨胀和性能的特性HOT元组
HOT元组的创建可能是PG对抗索引中不必要条目的强大武器。使用此功能UPDATE创建产生的元组不会被索引条目引用,它还会引用元组的老版本。通过这种方法,不需要创建新的索引条目,可以避免索引膨胀。
杀死索引条目
当索引扫描遇到一个指向死元组的条目时,标记该条目“killed”。后续索引扫描会在VACUUM删除他们之前跳过这些条目。此外,PG可以在索引页面已满时删除这样的条目,以避免页分裂。
PG14如何进一步减少索引膨胀
自下而上的索引元组删除比之前方法更进一步:他在索引页分裂即将发生前就删除指向死元组的索引条目。这可以减少索引条目的数量并避免昂贵的分裂,以及稍后VACUUM清理参数的膨胀。
在某种程度上,这执行了之前VACUUM的部分公众,在这点上可以避免索引膨胀。
案例
为了演示新功能效果,使用pgbench分别在PG13和14上执行操作:
测试表:
![image.png](https://file.elecfans.com//web2/M00/3A/37/poYBAGJCt2SADK2cAABvMBXrNv4233.png)
Pgbench名为bench.sql的脚本:
![image.png](https://file.elecfans.com//web2/M00/3A/3D/pYYBAGJCt2SAXXQXAACVigprw9s687.png)
我运行脚本 60000 次(6 个客户端 10000 次迭代),如下所示:
pgbench -n -c 6 -f bench.sql -t 10000 test
比较测试结果
我们使用pgstattuple扩展来获取psql 的索引统计信息:
![image.png](https://file.elecfans.com//web2/M00/3A/37/poYBAGJCt2SALVo-AABDCDJfL_8003.png)
这是我们在 v13 中得到的:
![image.png](https://file.elecfans.com//web2/M00/3A/3D/pYYBAGJCt2SAfKtRAAA3lC0LZFQ680.png)
对于 v14,结果是:
![image.png](https://file.elecfans.com//web2/M00/3A/37/poYBAGJCt2SAQcn3AAA4gChmGQQ514.png)
改进最大的时testtab_unchanged_idx。在13中,索引膨胀严重,而在14中仅有60%的膨胀(这对索引来说还不错)。在这里我们看到了新功能的最大影响。UPDATE不扫扫描那个索引,因此没有killed的索引条目,“自底向上的删除”可以删除足够的这样的条目避免分裂。
也可以衡量testtab_pkey。由于UPDATE扫描该索引,死的索引元组被killed,新特性在分裂前删除这些元组。与13相比,效果不太明显,因为13已经很好地避免索引膨胀了。
索引testtab_changed_idx无法从新特性中获益。因为这进解决了UPDATE不修改索引值的情况。如果想知道为什么testtab_unchanged_idx叶子密度比13低:删除了索引重复数据。
Pg_upgrade后我们可以使用这项功能吗?
索引的存储格式没有变,所以pg_upgrade PG12及之后版本创建的索引后会自动公众。但之前版本创建的索引,需要REINDEX后获益。记住,pg_upgrade仅拷贝索引文件,不会更改内部索引版本。
总结
PG14继续改进B-tree索引。这个特性虽不是革命性的,但有望为许多公众负载提供改进的性能,尤其是那些有大量更新的工作负载。
-
存储
+关注
关注
13文章
3959浏览量
84961 -
RAM
+关注
关注
8文章
1332浏览量
113943
发布评论请先 登录
相关推荐
Mysql索引是什么东西?索引有哪些特性?索引是如何工作的?
![Mysql<b class='flag-5'>索引</b>是什么东西?<b class='flag-5'>索引</b>有哪些<b class='flag-5'>特性</b>?<b class='flag-5'>索引</b>是如何工作的?](https://file1.elecfans.com/web2/M00/B8/C5/wKgZomWH6eqAFMrfAADx8vshyf0063.jpg)
如何在Delphi中使用Devart PgDAC连接PostgreSQL?
盘点一下PostgreSQL的几种常用脱敏方式
![盘点一下<b class='flag-5'>PostgreSQL</b>的几种常用脱敏方式](https://file1.elecfans.com/web2/M00/B4/61/wKgZomVuhGWAcsZyAAAJT7nxfFU781.jpg)
Format函数可以传递负索引吗
索引的底层实现详解
![<b class='flag-5'>索引</b>的底层实现详解](https://file1.elecfans.com/web2/M00/A7/5A/wKgaomUjYyaAJnjNAAKTVtSk1uc464.jpg)
索引是什么意思 优缺点有哪些
MySQL索引的常用知识点
为什么选择 PostgreSQL
PostgreSQL中可用的各种数据类型
PostgreSQL准确且快速的数据对比方法
![<b class='flag-5'>PostgreSQL</b>准确且快速的数据对比方法](https://file1.elecfans.com//web2/M00/A2/A3/wKgZomUAFzCAAt-NADXeTayEhQU628.gif)
膨胀阀工作可以应用伺服的哪些运动模式?
![<b class='flag-5'>膨胀</b>阀工作可以应用伺服的哪些运动模式?](https://file1.elecfans.com//web2/M00/A1/4B/wKgaomToSgOAAfMVAAYZm1FmNF8376.png)
如何快速完成PostgreSQL数据迁移?
![如何快速完成<b class='flag-5'>PostgreSQL</b>数据迁移?](https://file1.elecfans.com//web2/M00/90/72/wKgaomTZ2jeAMyNrAADiqpmJUqQ943.png)
智能管理,NineData支持最受欢迎数据库PostgreSQL
![智能管理,NineData支持最受欢迎数据库<b class='flag-5'>PostgreSQL</b>](https://file1.elecfans.com/web2/M00/8D/FB/wKgZomTCLCiAZhndAAUG1xKmS4Q697.png)
MySQL为什么选择B+树作为索引结构?
![MySQL为什么选择B+树作为<b class='flag-5'>索引</b>结构?](https://file1.elecfans.com/web2/M00/8D/46/wKgaomS4qkSANs3QAAAM92G3Lf0155.jpg)
评论