时光荏苒,岁月如梭。楼主已经很久没有更新了。之前说好的一周一更的没有做到。实在是事出有因,没能静下心来好好看代码。当然这不能作为我不更新的理由,时间挤挤还是有的,拖了这么久,该再写点东西了,不然人就怠懒了。不过这回,我准备写的精简些,一方面我想偷点懒省点时间,二来毕竟写太长大家也不一定爱看。

之前我说过的查询分析,查询重写和查询规划都是相当于是对查询的"编译"。那么编译完了就应该按照既定的策略去执行它。本篇就来介绍查询执行模块的代码(Executor),欢迎拍砖。

这部分我主要从以下五个部分介绍查询执行模块(很可能要分成四到五篇文章来阐述,毕竟是比查询规划还要复杂的模块):

1.查询优化策略
2.非可优化语句的执行
3.可优化语句的执行
4.计划节点
5.其它子功能介绍

查询执行器的框架结构如下图所示。
大数据培训,云培训,数据挖掘培训,云计算培训,高端软件开发培训,项目经理培训

在exec_simple_query函数中,调用查询编译模块之后,就进入了查询执行器模块。在该模块中,就是按照前一阶段查询规划模块锁生成的查询计划,有机第调用存储、索引,并发等模块来完成数据的读取或者修改的过程。

在本模块中,总共下属四个子模块,分别是:Portal、ProcessUtility、Executor和其他特定子功能模块。

我们知道,查询规划阶段将查询分为两种类型,在查询执行模块中,先由Portal模块识别查询类型(有计划树和无计划树),根据查询类型分别指派Executor模块和ProcessUtility模块进行处理。

这两个子模块的处理逻辑相差很大,执行过程和先关数据结构差异也很大。

对于Executor模块,它根据输入的查询计划树按部就班地处理数据表中元组的增删改查(DML)操作,它的执行逻辑是统一的(所有的增删改查最后都归结为SELECT,只是分别在SELECT的基础上进行一些额外的操作)。其主要代码放在src/backend/executor下。

而对于ProcessUtility模块,由于处理的是除了增删改查之外的所有其他操作,而这些操作往往差异很大,例如数据定义操作(DDL),事务的处理以及游标用户角色定义这些,因此在ProcessUtility模块中,为每种操作单独地设计了子过程(函数)去处理。主要代码在src/backend/commands下。

而剩下的我说的特定功能子模块,是指一些功能相对独立和单一并且在整个查询过程中会反复被调用的函数(我更愿意称他们为工具函数),例如各种辅助的子系统,表达式的计算,投影运算以及元组操作这些。


1.查询优化策略

在进入这一模块之前,我已经简要说明了Executor模块和ProcessUtility模块这两个主要的执行分支。这里要提到两个概念:

可优化语句和非可优化语句

可优化语句说白了就是DML语句,这些语句的特点就是都要查询到满足条件的元组。这类查询都在查询规划阶段生成了规划树,而规划树的生成过程中会根据查询优化理论进行重写和优化以提高查询速度,因此称作可优化语句。

那反过来讲,那些没有生成执行计划树的功能性操作就是非可优化语句了。这里只是提一下这个概念,在后面的介绍中会用。

延伸阅读

学习是年轻人改变自己的最好方式-Java培训,做最负责任的教育,学习改变命运,软件学习,再就业,大学生如何就业,帮大学生找到好工作,lphotoshop培训,电脑培训,电脑维修培训,移动软件开发培训,网站设计培训,网站建设培训学习是年轻人改变自己的最好方式