数据库系列-扫描路径

前言

上回说到选择率,这回顺着选择率到扫描路径。至于上集说的预告,希望你能从文中找到答案。

扫描路径

顺序扫描

顺序扫描又称全表扫描,是最基本的扫描方式,复杂度为O(N)。我的理解是,就是依次扫描整个堆表。

  • 优点:顺序访问效率比随机访问效率高,在PG中定义的,随机访问代价是顺序访问的4倍。
  • 缺点:对于选择率低的场景,代价太高了。因为堆表中的元组是无序的,如果想要筛选出我们想要的数据,就必须要全表扫描。
  • 我们想要避免SeqScan的本质,利用索引的有序性,大大减少需要扫描的记录数量来节省代价!

索引扫描

索引扫描是通过借助数据结构来提高查询性能。例如:
B树索引-复杂度O(logN)、Hash索引-复杂度O(1)
其本质是空间换时间。通过索引给数据建”目录“

  • 优点:由于(B树)索引的有序性,使得我们能够减少需要扫描的元组数量,从而提高效率。同时,还因为其有序性,使得我们能够快速得找到目标元组。
  • 缺点:排序意味着每次访问堆表的记录是随机访问的,在选择率较高的场景下,随机访问的代价也是很可观的。
  • 值得注意的是,索引记录的是目标元组所在的(block数据页, offset所在数据页位置),即(数据页, 所在数据页位置)。

小结

我们之所以想要避免SeqScan的本质是,在选择率低的场景下,全表扫描的元组数量太多了。而利用索引的有序性,我们并不需要扫描整个表。而在大多数业务场景下,通常选择率都是比较低的,所以我们希望数据库能够选择索引扫描。然鹅,统计信息如果不准确,数据库以为选择率比较高,就有可能放弃索引扫描!

位图扫描

为了应对索引扫描带来的随机扫描代价,PG通过位图索引进行优化。
原理是,将索引扫描获取到的元组位置信息进行排序,然后再根据排序后的元组位置信息从堆表中获取元组。从而避免随机访问。
应用:or和and条件选择。分别在索引上进行筛选(将条件拆开,分别筛选or/and的左边和右边),然后再合并条件后,recheck-重新检查合并后的条件。

需要注意的是,如果索引筛选出来的结果集还是比较大,那么PG就会转为lossy风格。即,只保留元组所在的数据页,而不保存元组具体的位置。这样在索引扫描后,就需要对这些筛选出来的数据页中的元组重新校验条件是否满足。如果这些元组刚好随机分布在全部数据页中,那么效率比SeqScan还要慢。除此之外,recheck需要将数据页中的元组读取之后才能依据元组中的字段来进行条件校验。意味着,内存占用也会比单纯的索引扫描大。

总结

  1. 统计信息如何对执行计划产生影响的:统计信息->选择率->扫描路径->执行计划。
  2. 绝大多数业务场景都是低选择率场景,因此我们希望数据库能够选择索引扫描来减少不必要的元组扫描来提高效率。
  3. 扫描路径主要有

    顺序扫描
    索引扫描
    位图扫描

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值