背景
场景:
- HTAP业务, 企业级OLTP业务.
- ORM(自动生成SQL, 无法优化, 数十表的SQL JOIN)
挑战:
- 优化器弱无法选择最佳执行路径,
- 统计信息不及时, 无法得出最佳执行计划,
- 环境: ssd, disk 多种不同硬件组成的表空间, 怎么才能算出最佳代价
- 执行器弱支持的数据扫描、计算方法少的可怜.
PG 解决方案:
- 优化器强大
- 执行器强大
- 支持扩展执行器
- 支持并行计算、JIT
PG的将军之官 - 优化器
谋虑的前提?
- 数据 案例 逻辑 理想
JOIN :
穷举的问题: N的阶乘种组合方式, 表多会导致组合太多, 导致优化器根本算不出来
PG支持:
- JOIN数超过设定参数, 自动使用遗传算法(图、TSP经典问题的解法)
- 参数可设置, 使用固定顺序
- 默认穷举
- aqo插件, 类似机器学习, 适合非常复杂的SQL
join算法 :
- nest(普通, 物化)
- merge
- hash
- limit优化
in大量value优化
- hash sub sets
并行计算:
- 根据SQL的代价自动启用并行计算, 适合AP场景
- 什么时候用并行? 参数阈值决定.
- 多大并行? 自动根据代价、表的大小等相关值计算
jit:
- 根据SQL代价自动启用JIT, 适合计算记录数多、表达式多的AP型SQL
- 什么时候? 参数阈值决定, 当代价大于阈值, 自动使用JIT
扫描方法怎么选择:
- 索引扫描
- 位图扫描
- 全表扫描
- ctid扫描
- ctid range scan
- 物化扫描等
- ...
代价因子, 可自定义
- 适合任意硬件组合, 选出更佳的计划
选择性怎么评估?
- 自动生成统计信息(根据数据的变化量自动生成, 所以统计信息很及时)
- 统计信息柱状图
- 高频次分布
- 自定义统计信息
- 唯一值个数
- 字段和存储的线性相关性
prepared statement时倾斜怎么办?
- 自动调整
- 《执行计划选择算法 与 绑定变量 - PostgreSQL prepared statement: SPI_prepare, prepare|execute COMMAND, PL/pgsql STYLE: custom & generic plan cache》
- 《PostgreSQL plan cache 源码浅析 - 如何确保不会计划倾斜》
custom scan provider开放接口, 适合内置scan方法不能解决的特定workload场景:
- GPU, pg_strom, heterodb
- citus column store, pg_pathman都用了custom scan provider. 提升性能.