作者:瀚高PG实验室 (Highgo PG Lab)
计划器解决的问题
1、发现一个好的查询计划。
2、不消耗大量的时间或内存来制定执行计划。
3、支持PostgreSQL扩展,如自定义数据类型、函数、运算符等。
计划是什么
计划是由计划节点构成的树。每个计划节点包含了执行器所需的所有细节,代表了一种特殊的处理类型:
关系扫描节点
顺序扫描、索引扫描、位图索引扫描
连接节点
嵌套连接、带内部索引扫描的嵌套连接、哈希连接、合并连接
特殊的计划节点
排序、聚合等
各访问策略的特点及适用情况
顺序扫描(Sequential Scan)
读取表中的每一行
不需要提前建立索引
不要求读取索引,因为会产生I/O和CPU成本
对很小的表来说是效果最好的方式
当需要访问表中的所有行或者接近所有行时的最佳选择
索引扫描(Index Scan)
读取部分表,通过使用索引跳过不感兴趣的部分
交替读取索引和表
当只读取大表中的一小部分行时可能会获得巨大的性能提升
唯一可以返回按顺序排序的行的表访问方法(和LIMIT结合使用会有非常好的效果)
位图索引扫描(Bitmap Index Scan)
先读取索引,填充位图,然后顺序读取表
表I/O是顺序的,可以跳跃,结果是物理次序的
可以有效地结合数据多索引-TID位图可以处理布尔类型的 AND 和OR运算符
处理LIMIT效果很差
计划器做出的决策最终决定了执行时间以及资源消费,我们可以使用EXPLAIN命令来找出可能的执行计划。
如果计划器低估了row count,它会选择使用索引扫描而不是顺序扫描,或者嵌套连接而不是哈希或者合并连接。
如果计划器高估了row count,它会选择顺序扫描而不是索引扫描,或者合并或哈希连接而不是嵌套连接。
LIMIT的值设定过小会使计划器向快启动计划倾斜,放大了坏估计的影响。