Oracle解释计划
2013-02-28 22:31
316 查看
一. 背景介绍
当我们质疑一条SQL语句执行缓慢,进而尝试是否有改进可能性的时候。我们往往需要查看这条SQL语句对应的执行计划,那么在oracle中如何获取执行计划是本文要介绍的内容。
二. 获取方法
oracle提供四种获取执行计划的方法:
1. 执行SQL语句explain plan,然后查询结果输出表(普遍方法)
2. 查询一张动态性能视图
3. 查询自动工作量库或者statspack表
4. 启动提供执行计划的跟踪功能(比如启动sql_trace)
三. SQL语句EXPLAIN PLAN(方法一)
这个命令是以一条SQL语句作为输入,得到这条SQL的执行计划,并且将结果输出到计划表中。语法如下:
explain plan for select count(*) from user_objects /*解析获取执行计划*/
select * from table (dbms_xplan.display) /*查询计划表显示执行计划*/
执行结果:
上图第一个红框是执行计划,执行计划展示的时候类似于一个表格形式,其实它是一个树形结构。该树形结构不仅阐述了SQL引擎执行操作的顺序,也阐明了它们之间的关系。树上的每一个节点都代表一个操作,比如表访问,连接,排序等。各操作之间存在父子关系,具体规则如下:
1. 父有一个或多个子
2. 子只有一个父
3. 唯一没有父的是根节点
4. 执行计划显示的时候,子缩进到父的右侧
5. 父在他孩子前面(父ID小于孩子的ID)
上图对应树形结构为:
第二个红框里面是对查询的解释,如:
1 - access("BONUS"."ENAME"="EMP"."ENAME")
序号为1的过滤条件为:"BONUS"."ENAME"="EMP"."ENAME" 序号4为access说明是按照条件有目的的去访问。filter表示全表扫描。
根据规则,此SQL执行顺序为:
3:TABLE ACCESS FULL EMP表得出14条记录
4:TABLE ACCESS FULL DEPT表得出1条记录
2:将3、4的结果整合,得出9条记录
5:TABLE ACCESS FULL BONUS表得出1条记录
1:将2、5的结果整合,得出8条记录
如果查看的是绑定变量SQL的执行计划,SQL必须是变量的形式,比如:
explain plan for select * from emp where empno = :p_value.
但是,存在一个问题,由于命令explain plan不能使用绑定变量窥测,也就是explain plan显示的执行计划,可能不是真正的执行计划。也就是说,如果使用了绑定变量,那么explain plan生成的执行计划是不可靠的(当然,这是针对绝对可靠而言,其实已经很可靠了)
四. 查询动态性能视图获取执行计划(方法二)
SQL语句被解析执行之后,会在共享池里面缓存着这条SQL语句的解析结果和执行计划,我们可以通过两个字段从动态性能视图里面查出执行计划(本地测试了一下,视图里面没找到数据)。一个是sql_id(父游标,代表一条SQL的解析结果),一个是sql_child_number(SQL语句执行计划序号,一条SQL可能对应多个执行计划),这两个字段在视图v$session和V$sql里面都存在。如果我们想查看的是当前正在执行SQL的执行计划,可以通过如下SQL查出这两个字段:
select a.SQL_ID, a.SQL_CHILD_NUMBER, b.SQL_TEXT
from v$session a, v$sql b
where a.SQL_ID = b.SQL_ID
and a.USERNAME is not null
and a.STATUS = 'ACTIVE';
查询到前两字段之后,直接通过一个dbms_xplan包的display_cursor函数就能查看这条SQL的执行计划,如下所示:
select * from table(dbms_xplan.display_cursor('2qx1ugfumvkyb', 0));
各条信息如下:
第一部分:
SQL_ID:识别父游标
child number:这个sql_id子游标序号,识别子游标
SQL文本内容:展示的是该执行计划是哪条SQL语句对应的
第二部分:
id列:步骤序号,如果前面有*,表示这一步会根据某一个过滤条件过滤数据。
opration列:执行的操作,比如索引扫描,选择数据,表连接等等。
name列:操作的对象,比如序号为3的操作是针对表主键T_PK的操作。
rows:此操作返回的记录条数。
bytes:此操作返回的记录字节数。
cost(%cpu):操作的开销,这是一个累计值。(我们可以看到序号4的操作开销最大)括号里面的值是cpu开销的百分比,比如0操作的百分比是97%,1操作的百分比是3%。
time:操作需要的时间,这也是一个累计值。(注意这个值可能不准确,因为oracle是采样计算的这个值)
当我们质疑一条SQL语句执行缓慢,进而尝试是否有改进可能性的时候。我们往往需要查看这条SQL语句对应的执行计划,那么在oracle中如何获取执行计划是本文要介绍的内容。
二. 获取方法
oracle提供四种获取执行计划的方法:
1. 执行SQL语句explain plan,然后查询结果输出表(普遍方法)
2. 查询一张动态性能视图
3. 查询自动工作量库或者statspack表
4. 启动提供执行计划的跟踪功能(比如启动sql_trace)
三. SQL语句EXPLAIN PLAN(方法一)
这个命令是以一条SQL语句作为输入,得到这条SQL的执行计划,并且将结果输出到计划表中。语法如下:
explain plan for select count(*) from user_objects /*解析获取执行计划*/
select * from table (dbms_xplan.display) /*查询计划表显示执行计划*/
执行结果:
上图第一个红框是执行计划,执行计划展示的时候类似于一个表格形式,其实它是一个树形结构。该树形结构不仅阐述了SQL引擎执行操作的顺序,也阐明了它们之间的关系。树上的每一个节点都代表一个操作,比如表访问,连接,排序等。各操作之间存在父子关系,具体规则如下:
1. 父有一个或多个子
2. 子只有一个父
3. 唯一没有父的是根节点
4. 执行计划显示的时候,子缩进到父的右侧
5. 父在他孩子前面(父ID小于孩子的ID)
上图对应树形结构为:
第二个红框里面是对查询的解释,如:
1 - access("BONUS"."ENAME"="EMP"."ENAME")
序号为1的过滤条件为:"BONUS"."ENAME"="EMP"."ENAME" 序号4为access说明是按照条件有目的的去访问。filter表示全表扫描。
根据规则,此SQL执行顺序为:
3:TABLE ACCESS FULL EMP表得出14条记录
4:TABLE ACCESS FULL DEPT表得出1条记录
2:将3、4的结果整合,得出9条记录
5:TABLE ACCESS FULL BONUS表得出1条记录
1:将2、5的结果整合,得出8条记录
如果查看的是绑定变量SQL的执行计划,SQL必须是变量的形式,比如:
explain plan for select * from emp where empno = :p_value.
但是,存在一个问题,由于命令explain plan不能使用绑定变量窥测,也就是explain plan显示的执行计划,可能不是真正的执行计划。也就是说,如果使用了绑定变量,那么explain plan生成的执行计划是不可靠的(当然,这是针对绝对可靠而言,其实已经很可靠了)
四. 查询动态性能视图获取执行计划(方法二)
SQL语句被解析执行之后,会在共享池里面缓存着这条SQL语句的解析结果和执行计划,我们可以通过两个字段从动态性能视图里面查出执行计划(本地测试了一下,视图里面没找到数据)。一个是sql_id(父游标,代表一条SQL的解析结果),一个是sql_child_number(SQL语句执行计划序号,一条SQL可能对应多个执行计划),这两个字段在视图v$session和V$sql里面都存在。如果我们想查看的是当前正在执行SQL的执行计划,可以通过如下SQL查出这两个字段:
select a.SQL_ID, a.SQL_CHILD_NUMBER, b.SQL_TEXT
from v$session a, v$sql b
where a.SQL_ID = b.SQL_ID
and a.USERNAME is not null
and a.STATUS = 'ACTIVE';
查询到前两字段之后,直接通过一个dbms_xplan包的display_cursor函数就能查看这条SQL的执行计划,如下所示:
select * from table(dbms_xplan.display_cursor('2qx1ugfumvkyb', 0));
各条信息如下:
第一部分:
SQL_ID:识别父游标
child number:这个sql_id子游标序号,识别子游标
SQL文本内容:展示的是该执行计划是哪条SQL语句对应的
第二部分:
id列:步骤序号,如果前面有*,表示这一步会根据某一个过滤条件过滤数据。
opration列:执行的操作,比如索引扫描,选择数据,表连接等等。
name列:操作的对象,比如序号为3的操作是针对表主键T_PK的操作。
rows:此操作返回的记录条数。
bytes:此操作返回的记录字节数。
cost(%cpu):操作的开销,这是一个累计值。(我们可以看到序号4的操作开销最大)括号里面的值是cpu开销的百分比,比如0操作的百分比是97%,1操作的百分比是3%。
time:操作需要的时间,这也是一个累计值。(注意这个值可能不准确,因为oracle是采样计算的这个值)
相关文章推荐
- oracle执行计划中NESTED LOOPS SEMI (即半嵌套循环)的解释
- ORACLE 执行计划中cost cardinality bytes cpu_cost io_cost解释
- oracle 优化之解释计划
- [转帖]Oracle执行计划解释
- Oracle之深入浅出(二)--SQL原理、解释计划与执行计划
- Oracle执行计划解释
- Oracle 解释执行计划
- Oracle执行计划解释
- Oracle执行计划解释
- Oracle执行计划解释(转)
- oracle执行计划解释
- oracle执行计划中NESTED LOOPS SEMI (即半嵌套循环)的解释
- Oracle性能优化之oracle中常见的执行计划及其简单解释
- Oracle执行计划解释
- oracle编程入门笔记2015-01-22--解释计划
- Oracle11高性能开发--(4)CBO和解释计划
- Oracle如何查看SQL的解释计划
- 创建自己的oracle解释计划
- (转)oracle执行计划中NESTED LOOPS SEMI (即半嵌套循环)的解释
- 创建自己的oracle解释计划