POSTGRESQL index-only-scan 到底开不开 与 我 羊 了

161b9f3512e9189f1ff763654ac75fbf.png

最近的任何人之间的问候语,与时俱进,见面一般第一句是,你阳了吗?然后就很容易打开话题了,至于阳不阳,这个问题,其实我是这样看的,你先在没阳,不证明你明天不阳,你阳过了,也要继续包含自己,持续增加自己的免疫力,锻炼身体,从现在开始爱护自己。有的时候问题的两方面看,从疾病中学到点什么,也不枉这3年,大家所付出的。努力的改变,欣然的接受,坦然的面对,然后在努力的改变,让自己持续的处于一个自己满意的状态。写这篇的时候,我已经感觉不大好了,可能已经阳了,这篇也许是最近能更新的最后一篇了,祝我好运吧。

最近问问题的同学挺多的,也有问有没有群的,实在是忙没有建群,所以问的人多了,想想还是建一个群,但本人写文章不懒,其他的比较懒,因为问POLARDB 的问题的多,所以建立了一个 POLARDB 和 PG ,MYSQL ,MOGNODB ,REDIS 以及文章问题的讨论群。希望能帮助自己也帮助大家共同提高,要进群的,可以添加微信 liuaustin3 ,来申请加群.

说完这一堆,有的没的,咱们的说到今天的主题了,POSTGRESQL 的INDEX ONLY SCAN ,因为最近我们遇到一个比较“诡异” 的现象,POSTGRESQL 的一个从库的执行的语句,一会快,一会慢。从几百毫秒,到几十秒。跨度还挺大的,那么到底一个语句到底为什么这样,的说说。

关键的地方在于 index -only -scan 这个POSTGRESQL 的功能,在使用中会不会出现一些问题,index-only-scan 为什么会产生这些问题。

96c803ec02debdf65b53cd5a5e7b9ec9.png

首先INDEX ONLY SCAN  产生于的思路是加快数据回馈的速度,也就是在扫描的情况下,数据的查询不会在回表。那么首先使用INDEX ONLY SCAN 的主要因素在于查询中的有适合的索引。

我们可以看到,在POSTGRESQL 中开启了index only scan ,从执行计划和执行的时间上看。

0d769c1c696451425db6c2524af10743.png

下面我们将这个部分index-only-scan 关闭,查看情况。

c631f3f5b98ffa5280f9bf3903d28115.png

第二种方式可以看到,将index only scan 关闭后,整体的查询的方式和选择的索引都变化了,虽然速度还是类似的,这里很明确的回表了。

首先这个索引本身在有些数据库中叫覆盖索引,也就是查询的return 的数据覆盖了整体的数据,也就是说,PG 如果要使用INDEX ONLY 必须有两个条件。

1  INDEX ONLY SCAN 打开

2  有合适的索引

在这样的情况下,很适合走 index only scan 索引,不通过回表的方式,直接通过INDEX  来将数据返回。

那么这里产生两个问题

1  我是用索引覆盖 还是用单索引,还是用include方式来进行数据的索引建立

2  一般的情况 index-scan-only 开不开

那么我们下面做一个实验,我们建立一个表,5百万的表

ff57ce7407a07d09df6a6ea116e7248f.png

我们分别用以下的几种索引来尝试查询的效率

1   单列索引  age  和  salary ,分别建立两个索引,然后查询的结果包含name

2   复合索引,其中查询的索引包含这三列

3  include 索引 ,复合的age  + salary  加include name

0d1f9871892e7b6d3e93760005a2cf8b.png

可以看到第一种方案中如果是分别建立两个索引的情况下,最终的结果是使用了单个索引来进行查询,并且回表了。

dc177b22579795fdd692dab885ab6e2e.png

查询的效率比之前的查询效率要高1.2倍左右。

那么问题来了,在什么情况下会出问题,这里测试环节在PG 14 版本中,这里只要使用ORDER BY ,那么INDEX-ONLY-SCAN ,这边立刻会出现问题,

a731fcf5b86221c5f36a22632b8fffa6.png

查询速度比较值钱慢了4倍之多,就是因为多了一个排序的部分,并且这部分不再索引内造成的。

具体分析一下首先如果没有排序的情况下,走的是我们标准的index-only-scan,  但是加了排序后,我们整个的过程就复杂了,直接走的是bitmap index scan ,然后多了一个 external merge 的部分对排序进行处理。

然后我们在将问题深入,将index only scan 关闭后看结果。在关闭后,我们发现整体的执行计划相对于原来的执行计划时间较少了100毫秒,并且不再有external merge 的部分。这里仅仅是关闭index only scan的情况。

76a49ab34caa5872aeffaac1dc9f9c20.png

那么这里我们将index only scan 打开,然后将id  作为索引的一部分,我们看看结果如何。

b30ff8103c56f4d01b93c7153d14ef7c.png

可以看到,执行的结果虽然已经走了我们建立了联合索引,但是这里还是有 extrnal merge 的部分。

写到这里,我浑身骨头疼,下面就简短说说 external merge, 出现这个情况是告知你的 process 的 work_mem 设置的少了,所以导致外部通过磁盘的方式来进行排序的处理。

在坚持一下,我调整我的虚拟机中的work_mem,看看情况是不是好转了,果然调整后,整体的操作的计划变化了,已经走了 quicksort : memory ,但是操作的速度并没有加快。但是情况并没有如愿,甚至还慢了。

7faa5e4ca6626c37ca25a3fa0f156aa2.png

而我再次关闭 index-only-scan ,查询的速度又提高了。我的结论是,如果你的PG 中存在大量的ORDER BY  并且不用ORDER BY 就很快,用了就很慢,那么你先试试关掉 INDEX-ONLY-SCAN 试试,速度有没有提升。

b3689e10e5c8b3b480d2003efd4ac361.png

实际上,还有很多东西需要研究,留到下一期,现在脖子,腰子,角统统的痛,嗓子和含了一个开水做的球一样。

本周估计是不能更新了,下周咱们见,阳了个阳, I AM BE OK !!

1dc53525c97eea8eeb1757a51a028cfc.png

841814452c2c96e5d63350ecb17b5aca.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值