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

通过执行计划看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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值