【DB吐槽大会】第18期 - PG 索引无版本信息

背景


1、产品的问题点

  • PG 索引无版本信息

2、问题点背后涉及的技术原理

  • PG 的索引没有TUPLE版本信息, 所以必须回表才能判断记录是否是dead tuple, 是否对当前事务可见.
    • 为了解决这个问题, PG引入VM file, 记录每个data block的状态, 当datablock为clean状态时, 则不需要回表, 但是也要访问VM才能判断datablock为clean状态呀, 所以离散IO次数是没有节省下来的, 节省的是IO覆盖范围, 毕竟VM里面2bit就表示1个data block(默认8KB).

3、这个问题将影响哪些行业以及业务场景

  • 对IO敏感的场景
  • 多对象的时序、时空场景, 对某个对象, 范围扫描大量记录, 需要回表, 产生大量离散IO. 例如查询某个车辆的轨迹.

4、会导致什么问题?

  • 即使采用 include index , 叶子节点包含需要查询的所有数据, 但是如果需要回表判断, 离散IO依旧是问题(从索引到table或VM文件都是离散IO).
  • 额外对table数据文件的回访, 导致浪费shared buffer.
  • 在删除大量数据后 或者 更新大量数据后, 如果索引的垃圾版本未及时进行垃圾回收, 将导致命中这部分索引的Query性能急剧下降.

5、业务上应该如何避免这个坑

  • 尽量不要使用更新, 使得大部分数据块内的记录都是对所有会话可见, 所以不需要回表查询, 减少IO.
  • 按对象ID分区, 使用BRIN索引代替BTREE索引, 减少时序类数据的范围搜索IO.

6、业务上避免这个坑牺牲了什么, 会引入什么新的问题

  • 管理复杂度增加

7、数据库未来产品迭代如何修复这个坑

  • 内核层支持索引版本



上一篇:史上最全Java学习路线:免费全套Java视频合集 (基础+进阶+高级+项目+面试题)


下一篇:快速安装python相关包&避免Read timed out