2021SC@SDUSC
目录
概述
我负责的PostgreSQL代码部分:查询的编译与执行
此篇博客的分析内容:查询优化——生成路径
查询优化的整个过程可以分为预处理,生成路径和生成计划三个阶段。在上一篇博客中,我分析了查询优化的第二个阶段——生成路径,并详细的介绍和分析了生成基本关系的访问路径的方法。在这篇博客中我会详细的介绍生成索引扫描路径,生成TID扫描路径以及最终的汇总之前的所有生成路径生成最终路径。
生成索引扫描路径
当关系上涉及索引扫描时,要生成相应的索引路径。生成索引路径的函数主要是create_index_paths函数
create_index_paths函数
该函数为参数rel中指定的RelOptInfo结构添加可能的索引路径。
一个索引必须满足以下条件之一才会被考虑用于生成索引扫描路径:
能匹配一个或者多个约束条件(来自于baserestrictinfo字段中的RestrictInfo结构)
能匹配查询中的连接条件
能匹配查询的排序要求
能匹配查询的条件(where子句中除了连接条件的其他条件)
create_index_paths(PlannerInfo *root, RelOptInfo *rel)
{
List *indexpaths;//存储索引路径的链表
List *bitindexpaths;//位图索引路径
List *bitjoinpaths;//位图路径
List *joinorclauses;//链接子句
IndexClauseSet rclauseset;//限制性条款
IndexClauseSet jclauseset;//存放连接子句的集合
IndexClauseSet eclauseset;//连接语句的等价类
ListCell *lc;//临时变量
//判断有无索引,如果没有索引,就跳过整个过程
if (rel->indexlist == NIL)
return;
//收集位图路径,然后在最后处理
bitindexpaths = bitjoinpaths = joinorclauses = NIL;
//依次检查每个索引
foreach(lc, rel->indexlist)
{
IndexOptInfo *index = (IndexOptInfo *) lfirst(lc);
//在IndexClauseSets中保护有限大小的数组
Assert(index->nkeycolumns <= INDEX_MAX_KEYS);
//忽略不符合查询的部分索引。
if (index->indpred != NIL && !index->predOK)
continue;
//识别可以匹配索引的限制性条款
MemSet(&rclauseset, 0, sizeof(rclauseset));
match_restriction_clauses_to_index(root, index, &rclauseset);
//从限制性条款中建立索引路径,普通路径直接进入add_path(),位图路径被添加到bitindexpaths中
get_index_paths(root, rel, index, &rclauseset,
&bitindexpaths);
//识别可以匹配索引的连接子句,这一步只找到未被合并到等价类中的 "松散 "连接子句,还要收集连接OR子句以备后用。
MemSet(&jclauseset, 0, sizeof(jclauseset));
match_join_clauses_to_index(root, rel, index,
&jclauseset, &joinorclauses);
//寻找能够生成与索引相匹配的连接语句的等价类
MemSet(&eclauseset, 0, sizeof(eclauseset));
match_eclass_clauses_to_index(root, index,
&eclauseset);
//如果找到任何普通的或类的连接子句,用它们建立参数化的索引路径
if (jclauseset.nonempty || eclauseset.nonempty)
consider_index_join_clauses(root, rel, index,
&rclauseset,
&jclauseset,
&eclauseset,
&bitjoinpaths);
}
//为限制列表中任何合适的or子句生成BitmapOrPaths
//调用generate_bitmap_or_paths函数为baserestrictinfo中的OR子句生成BitmapOrPath路径,并将它们加入到bitindexpaths链表中
indexpaths = generate_bitmap_or_paths(root, rel,
rel->baserestrictinfo, NIL);
bitindexpaths = list_concat(bitindex