ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Oracle的执行计划---SQL的执行规律

Oracle的执行计划---SQL的执行规律

原创 Linux操作系统 作者:jump2009 时间:2010-10-13 09:57:51 0 删除 编辑

在说执行计划之前先说一下概念性的术语.

共享SQL语句:

   为了不重复相同的SQL语句,在第一次解析后,oracle将SQL语句及解析后得到的执行计划存放在内存中,它位于

SGA的共享池中,可以被所有的数据用户共享.所以,在你执行一个SQL语句时,如果它和先前执行过的一条SQL语句相

同的话,oracle就不会再对它进行分析了,这样提高了SQL执行性能并大大节省了内存使用.在这里要注意oracle对两

者采取的是一种严格匹配。要达到共享SQL语句就必须相同(包括空格,换行等,就像是复制过来的一样)。

 

2.Rowid的概念:

   rowid是一个伪列,就是用户不用定义的列,是系统自动加上去的,每个表都有一个rowid的伪列,你可以像使

用其它列一样使用伪列,但是不能对它进行修改,删除,行的rowid是固定不变的。

    再说一下咱们为什么使用rowid,因为rowid对访问表时提供了一种最快的访问方法,通过rowid可以直接定位到

相应的数据块上,然后再将其读入内存,在我们定义一个索引时,该索引也存储了rowid所以这也是为什么我们在

使用索引时,速度比较快的原因。

 

Recursive SQL的概念:

   有时候我们在执行一条SQL语句时oracle 必须执行一引起额外的语句,这些额外的语句称为recursive call 或

recursive SQL statements 。例如当一个DDL语句发出后,oracle总是隐含地发出一些recursive SQL语句,用来

修改数据字典信息,来确保用户可以成功地执行DDL语句。当需要的数据字典没有在内存中时它会发生recursive

call。这些recursive call会将数据字典信息从硬盘读入内存中。

 

Row Source(行源)

    它是在查询中返回的符合条件的集合,它可以是全部行数据的集合也可以是部分行数据的集合,也可以是对两

个或两个以上的 row source 进行连接操作后得到的集合(join)。

 

Predicate(谓词)

    一个查询中的where限制条件

 

Driving Table(驱动表):

    咱们也可以叫它外层表(outer table)。如果该 row source返回较多 的数据,刚对后续的操作有负面影响。

一般来说,它应用于查询限制条件后,返回较少行源的表做为驱动表,所以如果一个where条件有有限制条件(如

等值限制),则该大表做为驱动表也是合适的,也并不是少天做为驱动表,正确的说法应该为应用查询的限制条件

后,返回较少行源的表作为驱动表,

 

Probed Table(被探查表):

      该表又称内层表(inner table),我们从驱动表中得到具体一行的数据后,在该表中寻找符合连接条件的行

,所以该表该为大表(返回较大row source的表)且相应的列上应该有索引。

 

组合索引(concatenated index)

    由多列构成的索引,如create index 索引名 on 表名(col1,col2,.....),在组合索引中也有一个重要的

概念:引导列(leading column) 哪个是引导列呢?col1这列就是引导列,在查询时 "where col1 = ?" 或"where

col1= ? and col2 = ?" 这里都会使用索引,但是"where col2 = ? "这时不会使用索引。所以在限制条件中应该

包含先导列时,该限制条件才使用索引。

 

可选择性(selectivity)

    比较一下列中唯一键的数量和表中的行数,就可以判断该列的可选择性,如果该列的“唯一键的数量/表中的

行数“ 越接近1则可选择性越高。在选择性高的列上进行查询时,返回的数据就较少,比较适合使用索引查询。

 

 

OK,有了这些背景知识就开始说一下执行计划,为了执行语句,oracle 可能必须实现许多步骤,可能是从数据库

中物理检索数据行,也可能是用某种方法准备数据行,供发出语句的用户使用。oarcle用来执行语句的这些步骤的

组合被称为执行计划。执行计划是SQL优化中最为复杂也是最为关键的部分,只有知道了oracle在内部如何执行SQL

语句后,我们才能知道优化器选择的执行计划是否为优的,现在我们的主要问题是:如何得到执行计划,如何分析

执行计划,从而找出影响性能的主要问题。现在先从分析树弄执行计划开始介绍,然后介绍如何得到执行计划,再

介绍如何分析执行计划。

 

先举个例子:

    就先说说现在这条SQL语句的执行计划

        select emp_name,job,emp_salary,dept_name

           from emp,dept

           where emp.deptno = dept.deptno

             and not exists

                 (select *

                    from salgrade

                    where emp.emp_salry between losal and hisal);

这条语句是查询薪水不在任何建议薪水范围的所有雇员的名字,工作,薪水和部门名。

如图显示了一个执行计划的图形表示:

http://album.hi.csdn.net/app_uploads/ailandle/20090107/011853137.p.jpg?d=20090107011934668

 

 

首先来看一下执行计划的步骤:

   执行计划的每一步返回一组行,它们或者为下一步使用或者在最后一步时返回给发出SQL语句的用户或应用,由每一步返回的一组叫做行源。

     上图由红色标识的是从数据库中的数据文件检索出来的数据。这步叫存储路径。

接着分析一下它的步骤吧!

第3,6步分别从emp,salgrade两个表中读出所有行。

第5步在pk_deptno索引中查找由步骤3返回的每个deptno值,它找出与dept表中有相关联的那些行的rowid

第4步从dept表中检索出rowid为第5步返回的那些行。

黑色字框指出的步骤在行源上操作,如两个表之间的关联,排序,过滤等操作

第2步实现嵌套的操作就做是C的嵌套循环,接收第3步和第四来的行源,把第3步的每一行与第4小相应的行连接在一起,返回到第一步。

第1步是完成一个过滤器的操作,接收2,6,步来的行源,返回给用户发出的SQL语句或回应

 

再详细说一下执行计划顺序

    它并不是完全执照给它们的编号来实现的,它是以下列顺序来实现的这些步骤的:

首先 Oracle实现了步骤3,并一行一行地将结果返回给第2步

对第3步返回的每一行,Oarcle又实现了这些步骤

 1.实现第5步,并将结果的rowid返回给第4步

 2. 实现第4步,并将结果返回给第2步

 3.实现第2步,接收来自第3步的一行和第4步的一行,返回给第一步

 4.实现第6步,如果它有值就返回给第一步

 5.实现第1步,如果6返回行,oracle就将2得到的结果返回给发出SQL语句的用户。

 

在这里要注意一下,oracle是由第3步返回的每一行实现步骤5,4,2,6一次,在它们父步骤执行之前只需要来自它们子步骤的单一行。

对于这样的父步骤来说只要子步骤返回单一行就可以实现父步骤,如果父步骤的父步骤同样可以通过单一行被激活的话,那么它也同样被执行。如果执行可以串连下去,可能包含执行计划余下的部分,对于这样的操作可以使用first_rows作为优化目标以便于实现快速响应用户的请求。

-----------------------------小插曲------------------------------------------------------

判断当前数据库使用何种优化器:
由optimizer_mode裙化参数决定的它的值可以设置为:first_row_[1 | 10 | 100 | first_rows | all_rows | choose |rule ]
rule:为使用RBO优化器
choose:如果对象已被解析就用CBO,否则就用RBO
all_rows:CBO优化器使用的第一种具体的优化方法,以吞吐量为主要目标,以便使用最小的资源完成语句
first_rows:CBO优化器使用的第一种具体的优化方法,以数据的响应时间为主要目标,以便快速查询出开始的几行数据
first_rows_[1 | 10 | 1000] CBO优化器使用的第一种具体的优化方法,迅速产生查询结果的前n行
---------------------------------------------------------------------------------------------

但是有些父步骤在它们实现之前需要来自子步骤的所有行。对于这样的父步骤,直到所有行从子步骤返回之前Oracle不能实现该步骤。这样的步骤包括排序,排序---合并的连接,组功能和总计,对于这样的不能用first_rows作为优化目标,而要用all_rows,使操作耗费的资源最少。

 

有的时候在语句执行过程时,也并不像上面所说的那样一步一步有先后顺序地进行,也有并行运行的时候,其中3,4,5步可能并行进行。以便取得更好的效率。所以它要通过另一种形式的执行计划。则可以很容易地看出哪个先执行,哪个后执行,这样的执行计划才是我们真正想要的。

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/18953778/viewspace-675807/,如需转载,请注明出处,否则将追究法律责任。

下一篇: 理解REDO LOG
请登录后发表评论 登录
全部评论

注册时间:2009-02-17

  • 博文量
    43
  • 访问量
    78124