3.2 解读执行计划
3.2.1 执行顺序
当我们阅读一个执行计划时,理解执行计划的执行顺序非常重要。这对于我们理解语句实际执行过程,评估各个步骤可能的开销并进而采取优化策略等都有很大的帮助。遗憾的是,Oracle本身并没有提供一个直观的方法可以一目了然地看到语句的执行顺序,需要我们自己根据一些规则去判断执行顺序。下面针对这些规则加以说明。
·执行计划是由很多步骤组成的,步骤之间有一定的执行顺序。每个步骤都有一个编号。
·步骤之间存在父子关系。父子关系是通过缩进来体现的,子节点会较父节点向右缩进。而父节点就是子节点上面离它最近的左移节点。如图3-1所示,节点1是父亲,节点2、3是它的孩子,而节点3又是节点4、5的父亲。
·父子节点之间的缩进结构形成了一个树形图。真正执行顺序是从树形顶部开始,自上而下、自左向右寻找,直到到达某个节点(这个节点没有子节点),首先执行此节点。此后执行此节点同级的节点,执行顺序从上而下。在树形结构中,如果某个节点还有子节点,则先执行子节点;执行结果不断上移到父节点,直到汇总到顶级节点。还以图3-1所示为例,按照自上而下、自左向右的顺序,找到第一个没有子节点的节点是节点2,执行此节点;然后自上而下找到节点3,因为节点3还有子节点,所以先执行这些子节点。以此类推,整个的执行顺序就是2-4-5-3-1。
图3-1 步骤之间的父子关系
下面通过一个示例,详细说明执行顺序。
SELECT ename,job,sal,dname FROM emp,dept WHERE dept.deptno=emp.deptno and not exists ( SELECT * FROM salgrade WHERE emp.sal between losal and hisal ); -------------------------------------------------- | Id | Operation | Name | -------------------------------------------------- | 0 | SELECT STATEMENT | | |* 1 | FILTER | | | 2 | NESTED LOOPS | | | 3 | TABLE ACCESS FULL | EMP | | 4 | TABLE ACCESS BY INDEX ROWID| DEPT | |* 5 | INDEX UNIQUE SCAN | PK_DEPT | |* 6 | TABLE ACCESS FULL | SALGRADE | --------------------------------------------------
·整个执行计划有Id=0~6,总共7个步骤。在Operation列采用缩进格式显示。
·执行顺序从Id=0开始,按照自上而下、自左到右,寻找缩进层次最深且没有子节点的节点。在上面的执行计划中,Id=3是满足条件的节点(Id=5虽然缩进层次更深且没有子节点,但其父节点Id=4与Id=3的节点是兄弟关系,且从Id=0顶节点往下找到第一个没有子节点的节点是Id=3的节点,因此Id=3的节点是先执行的节点)。
·对于Id=4和Id=5这两个节点,是父子关系。按照先子节点后父节点的顺序执行,即先执行Id=5节点,然后执行Id=4节点。
·子节点执行完毕后,将结果返回到上级节点。例如上面的Id=3、4、5执行完毕后,结果集汇总到Id=2。
上例整个执行顺序为3-5-4-2-6-1-0。
3.2.2 访问路径
在执行计划中的Operation列,对应的就是访问路径,即这个步骤是如何访问数据的。常见的有如下的一些分类。
·表相关的访问路径:这部分主要包括ROWID表扫描、采样表扫描、全表扫描三种方式。即针对表的访问,可以按照上面三种方式中的一种进行。
·索引相关的访问路径:这部分又可分为B树索引访问路径和位图索引访问路径。B树索引访问路径主要包括索引唯一扫描、索引范围扫描、索引全扫描、索引快速全扫描、索引跳跃扫描等方式。位图索引访问路径包括位图索引单键扫描、范围扫描、全扫描、快速全扫描及按位与、或、减等方式扫描。
·表关联相关的访问路径:这部分主要包括嵌套循环连接、排序合并连接、哈希连接、笛卡儿连接等方式。
·和SORT相关的访问路径:这部分包括聚合、去重、分组、排序等排序访问方式。
·其他的访问路径:这部分包括视图、集合、层次查询等访问方式。
如何理解访问路径这个概念呢?这里举一个简单的示例,后文将有对这些执行路径的详细介绍。例如,我们需要对一个数据表做计数工作,即统计有多少条记录。如果是采用全表扫描的访问路径,则是按照表中记录的存储顺序,以块为单位,全部访问所有数据记录。