openGauss内核分析(七):SQL by pass & 经典执行器
执行引擎一般负责查询的执行,执行引擎在SQL执行栈中起到接收优化器生成的执行计划Plan、并对通过存储引擎提供的数据读写接口,实现对数据进行计算得到查询的结果集。

在典型的OLTP场景中,简单查询占了很大一部分比例。这种查询的特征是只涉及单表和简单表达式的查询,因此为了加速这类查询,openGauss提出了SQL by pass框架,在parse层对这类查询做简单的模式判别后,进入到特殊的执行路径里,跳过经典的执行器执行框架,包括算子的初始化与执行、表达式与投影等经典框架,直接重写一套简洁的执行路径,并且直接调用存储接口,这样可以大大加速简单查询的执行速度。
SQL by pass
enable_opfusion用于控制是否对简单增删改查进行优化,简单insert语句在开启enable_opfusion时的执行计划如下

由于开启SQL BY PASS,从exec_simple_query过来的语句,会判断可以走SQL BY PASS,否则进入CreatePortal走经典执行流程。
进入InsertFusion::execute完成数据插入操作。
SQL by pass适应的场景有:
只支持indexscan和indexonlyscan,且全部WHERE语句的过滤条件都在索引上。
只支持单表增删改查,不支持join、using。
只支持行存表,不支持分区表,表不支持有触发器。
不支持active sql、QPS等信息统计特性。
不支持正在扩容和缩容的表。
不支持查询或者修改系统列。
只支持简单SELECT语句,例如
仅可以查询目标表的列,c1和c2列为索引列,后边可以是常量或者参数,可以使用 for update。
Ÿ 只支持简单INSERT语句,例如:
仅支持一个VALUES,VALUES里面的类型可以是常量和参数,不支持returning。
Ÿ 只支持简单DELETE语句,例如:
c1和c2列为索引列,后边可以是常量或者参数。
Ÿ 只支持简单UPDATE语句,例如
c3列修改的值可以是常量和参数,也可以是一个简单的表达式,c1和c2列为索引列,后边可以是常量或者参数。
经典的执行器
关闭enable_opfusion,简单insert的执行计划是这样的

在这种执行流程中Portal是执行SQL语句的载体,每一条SQL对应唯一的Portal,不同的查询类型对应的Portal类型也有区别。
Portal的生命周期管理在exec_simple_query函数中实现,该函数负责Portal创建、执行和清理。Portal执行的主要执行流程包括PortalStart函数、PortalRun函数、PortalDrop函数几个部分。其中PortalStart函数负责进行Portal结构体初始化工作,包括执行算子初始化、内存上下文分配等;PortalRun函数负责真正的执行和运算,它是执行器的核心;PortalDrop函数负责最后的清理工作,主要是数据结构、缓存的清理。

PortalRun函数根据查询类型进入不同的处理函数
最终执行ExecInsertT完成数据插入。
以上分析了简单insert语句的两种执行流程,对于delete,update,select基本工作流程一致。

