您的位置:首页 > 数据库

通过执行计划看sql的执行路径

2009-06-28 22:13 309 查看
通过执行计划看sql的执行路径
今天又有网友问到了有关执行计划的步骤的问题。通过这个网友给的例子,我就简单的先讲讲执行计划里我们使用频率最高,也是最基础的一项,执行计划的路径问题。

这个网友给的是一个最简单的例子,是sample数据里的emp和dept的联合查询的例子

SQL>select ename,dname from emp,dept where emp.deptno=dept.deptno;

执行计划
----------------------------------------------------------
Plan hash value: 351108634

----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 308 | 4 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | 14 | 308 | 4 (0)| 00:00:01 |
| 2 | TABLE ACCESS FULL | EMP | 14 | 126 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS BY INDEX ROWID| DEPT | 1 | 13 | 1 (0)| 00:00:01 |
|* 4 | INDEX UNIQUE SCAN | PK_DEPT | 1 | | 0 (0)| 00:00:01 |
----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

4 - access("EMP"."DEPTNO"="DEPT"."DEPTNO")

以上是这个sql的执行计划,关于上面这个执行计划是如何出现的,这里不再赘述。我们直接从如何理解这个sql的执行路径开始。

通过这个sql和他的执行计划来看。这条SQL使用CBO的可能性高于RBO的可能性。虽然这里没有一个明确的Optimizer=XXXX的提示。主要是根据驱动表的顺序来猜测的,当然关于这个Optimizer并不是这里的主要内容。

那么根据这个执行计划的结果,我们如何来理解这个SQL的执行顺序叻,其实方法很简单,就是 同级,从上至下,不同级 从右及左。简单的口诀如此,

我们一起通过上面的实例来详细解释一下。

首先执行计划结果是一个树状结构,其中的一些step存在着父子的关系。最上面的就是root,我们可以把这个树简单的描述成

root

first sub-statement

second sub-statement

这里我们所说的同级,从上至下,不同级 从右及左, 表现就是,不同级 从右及左,也就是先执行子句(子句一般较右),子句的结果作为执行父句的依据。 所以这里要先执行完子句才用子句的返回来执行父句。 同级,从上至下, 就很好理解了,意味着first sub-statement和second sub-statement同级,那么先开始上面的,再执行底下的。

现在我们回看到这个sql的执行实例。

0 | SELECT STATEMENT | | 14 | 308 | 4 (0)| 00:00:01 |

这个是root,执行从这里开始。不过他下面还有

| 1 | NESTED LOOPS | | 14 | 308 | 4 (0)| 00:00:01 |

所以这里必须先执行完1,才能执行0的。 执行1,我们又可以看到。需要执行

| 2 | TABLE ACCESS FULL | EMP | 14 | 126 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS BY INDEX ROWID| DEPT | 1 | 13 | 1 (0)| 00:00:01 |

由于2下面已经没有子句了,所以这里2可以执行了,2执行完,接着还有3要执行呀。执行到3,我们又发现,3是需要先执行子句

|* 4 | INDEX UNIQUE SCAN | PK_DEPT | 1 | | 0 (0)| 00:00:01 |

这样先执行了4, 执行完4,4的结果返回给3,作为3执行的一些输入。

当3执行完,汇总2,3的执行结果返回执行1. 1执行完,就返回作为0最后的结果,从而sql执行完毕

所以我们这里最后可以看到这个sql的执行路径是 (2)->(4)->(3)->(1)->(0)

既是emp full scan(2) ----> dept index scan(4) ----> 由索引得到rowid ,读取数据 (3) ----> (1)返回本次查询结果。嵌套循环,直到得到所有结果。

执行计划的结果和优化器的模式,数据库的统计信息都有着比较密切的联系。所以相同的sql在不同的数据库上,甚至有时候是相同的数据,都有可能是不一样的执行计划的。

比如,我机器上的这个sql的执行计划是

---------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

---------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 4 | 40 | 7 (15)| 00:00:01 |

|* 1 | HASH JOIN | | 4 | 40 | 7 (15)| 00:00:01 |

| 2 | TABLE ACCESS FULL| EMP | 4 | 12 | 3 (0)| 00:00:01 |

| 3 | TABLE ACCESS FULL| DEPT | 5 | 35 | 3 (0)| 00:00:01 |

---------------------------------------------------------------------------

这里可以看到和网友的执行计划,相差很大,其实这里是基于CBO的,在不同的统计量下这个计划都会发生变化的。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/inthirties/archive/2009/06/28/4304864.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: