postgres之索引hot更新机制

一,传统的索引更新机制
背景:当数据行被更新时,因为postgres采用的是MVCC多版本并发控制,所以会导致更新一个数据时其实旧行数据还在,又新插入了一行数据,一行数据多个版本.
传统的更新过程是:
如果更新了一列数据,这个列上是有索引的,那么索引必然会被更新(同时多了一个版本的数据项和索引项);
如果更新了一列数据,这个列上是没有索引的,但是因为更新时新插入一行数据,新行的物理位置发生了变化,所以索引还是会被更新(同时多了一个版本的数据项和索引项).
二 hot更新机制(只是多了一个版本的数据项)
如果更新后,旧行和新行是在同一个块内,那么旧行会有指针(t_ctid)指向新行(t_ctid),就不用更新索引了.(行数据t_ctid指向新行数据t_ctid)
索引会先找到旧行,进而找到新行.
如果vacuum后,因为死块的存储空间被收回,这时候旧行数据的行指针会指到新行数据的指针,所以也不用更新索引,索引会先找到旧行,进而找到新行.(页面开头的行指针会指向新行指针)
如果删除数据项后,表中不能被回收的dead tuple在索引页里是作为正常tuple而不是dead tuple记录的。
三 hot更新使用条件
第一:更新的列上没有索引,而且索引列上的值没有变,因索引列质变的话所有索引都要新增一个版本.
第二:新老数据行必须在同一个数据块内,如果原来的数据块无法放下新行,则无法使用hot.
所以针对这种情况,如果一张表上经常做update操作,可以设置数据块的填充因子,使更新操作的新旧行位于同一个数据块内
–数据块填充到达50%后,就不再insert数据,剩余的空间被保留给该页上行的update。
–一个表的填充因子是一个 10 到 100 之间的百分数。100(完全填满)是默认值。当一个较小的填充因子被指定时,INSERT操作会把表页面只填满到指定的百分比,每个页面上剩余的空间被保留给该页上行的更新。这就让UPDATE有机会把一行的已更新版本放在与其原始版本相同的页面上,这比把它放在一个不同的页面上效率更高。对于一个项从来不会被更新的表来说,完全填满是最好的选择,但是在更新繁重的表上则较小的填充因子更合适。这个参数不能对 TOAST 表设置。

fillfactor越小,那么update时,就更有可能把新旧元组放到同一个页面,有助于索引hot更新机制运行,提高索引更新的效率

postgres=# alter table a set (fillfactor = 50);
ALTER TABLE

参考文章:
https://blog.csdn.net/chucui2049/article/details/100666621
https://blog.csdn.net/weixin_33674976/article/details/89561881?

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值