当前位置:数据库 > Oracle >>

Oracle生成和显示执行计划的方法

Oracle生成和显示执行计划的方法
 
生成执行计划
一条合法的语句在执行之后,就会在内存中至少产生一条执行计划,可以从视图v$sql_plan查询。每一条执行计划对于一个游标。一条语句生产的第一个游标的CHILD_NUMBER(即v$sql_plan中的CHILD_NUMBER)为0,同一条sql语句可能因为环境或版本等其他因素不同而产生不同的执行计划,也就是说一条sql可能有多个CHILD_NUMBER。
  www.zzzyk.com  
除执行过的sql会在内存中生成执行计划外,还可以通过explain plan让优化器对sql语句进行解析,生成查询计划。执行explain plan命令后,oracle会将解释生成的执行计划插入sys.plan_table$(10g之前,表名为plan_table;10g之后,通过公共同义词plan_table指向sys.plan_table$)中。explain plan产生的执行计划不会在语句执行时重用,而是以类似explain plan for<SQL>的形式在缓存中。
 
显示执行计划
 通过DBMS_XPLAN包显示执行计划(推荐)
DBMS_XPLAN含有5个函数用于输出格式化的执行计划,如下:
display:显示explain plan命令解释的执行计划
display_cursor:显示内存中的执行计划
display_awr:awr历史数据中的执行计划
display_sqlset:SQL优化集中语句的执行计划
display_sql_plan_baseline:SQL执行计划基线
  www.zzzyk.com  
display的用法
语法:
DBMS_XPLAN.DISPLAY(
   table_name    IN  VARCHAR2  DEFAULT 'PLAN_TABLE',
   statement_id  IN  VARCHAR2  DEFAULT  NULL, 
   format        IN  VARCHAR2  DEFAULT  'TYPICAL',
   filter_preds  IN  VARCHAR2 DEFAULT NULL);
参数:
Parameter Description
table_name
存储查询计划的表名,默认值为PLAN_TABLE
statement_id
要显示查询计划的SQL语句的ID,如果为空,就会获取最近一条被解释的语句
format
输出格式,有以下几种预定义的格式可选择,还可以自定义(这里不多说):
BASIC:基本格式,内容最少.
TYPICAL: 典型格式,通常够用,默认格式
SERIAL: 串行执行格式,这种格式和典型格式输出内容基本一致,只是对于并行查询,不会输出相关的并行内容
ALL: 完全格式,输出内容相对完整
filter_preds
该参数用谓词条件过滤存储执行计划的表,例如'plan_id = 10或cost>100(显示估算代价大于100的操作),该值默认为空
示例:
[html] 
用explain plan执行sql语句:  
  
EXPLAIN PLAN FOR  
SELECT * FROM emp e, dept d  
   WHERE e.deptno = d.deptno  
   AND e.ename='benoit';  
Display the plan using the DBMS_XPLAN.DISPLAY table function  
  
SET LINESIZE 130  
SET PAGESIZE 0  
SELECT * FROM table(DBMS_XPLAN.DISPLAY);  
输出结果如下  
  
Plan hash value: 3693697075  
---------------------------------------------------------------------------  
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |  
---------------------------------------------------------------------------  
|   0 | SELECT STATEMENT   |      |     1 |    57 |     6  (34)| 00:00:01 |  
|*  1 |  HASH JOIN         |      |     1 |    57 |     6  (34)| 00:00:01 |  
|*  2 |   TABLE ACCESS FULL| EMP  |     1 |    37 |     3  (34)| 00:00:01 |  
|   3 |   TABLE ACCESS FULL| DEPT |     4 |    80 |     3  (34)| 00:00:01 |  
---------------------------------------------------------------------------  
  
Predicate Information (identified by operation id):  
---------------------------------------------------  
   1 - access("E"."DEPTNO"="D"."DEPTNO")  
   2 - filter("E"."ENAME"='benoit')  
  
15 rows selected.  
 
display_cursor的用法
display_cursor可以显示内存中一个或多个游标的执行计划.
语法:
DBMS_XPLAN.DISPLAY_CURSOR(
   sql_id        IN  VARCHAR2  DEFAULT  NULL,
   child_number  IN  NUMBER    DEFAULT  NULL, 
   format        IN  VARCHAR2  DEFAULT  'TYPICAL');
参数:
Parameter Description
sql_id
要显示执行计划的sql语句的ID
child_number
子游标序号
format
输出格式
同于display输出格式
 
示例:
[html] 
<span style="color:#009900;">display_cursor 默认是获得由本session执行的之后一条语句的执行计划:</span>  
  
SELECT ename  FROM  emp e, dept d   
   WHERE   e.deptno = d.deptno    
   AND   e.empno=7369;  
  
ENAME  
----------  
SMITH  
  
SET PAGESIZE 0  
SELECT * FROM table(DBMS_XPLAN.DISPLAY_CURSOR);  
<span style="color:#009900;">输出结果如下:</span>  
Plan hash value: 3693697075, SQL hash value: 2096952573, child number: 0  
------------------------------------------------------------------  
SELECT ename FROM emp e, dept d WHERE e.deptno = d.deptno  
AND e.empno=7369  
  
---------------------------------------------------------------------------  
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |  
---------------------------------------------------------------------------  
|   0 | SELECT STATEMENT   |      |       |       |            |          |  
|*  1 |  HASH JOIN         |      |     1 |    16 |     6  (34)| 00:00:01 |  
|*  2 |   TABLE ACCESS FULL| EMP  |     1 |    13 |     3  (34)| 00:00:01 |  
|   3 |   TABLE ACCESS FULL| DEPT |     4 |    12 |     3  (34)| 00:00:01 |  
---------------------------------------------------------------------------  
  
Predicate Information (identified by operation id):  
---------------------------------------------------  
   1 - access("E"."DEPTNO"="D"."DEPTNO")  
   2 - filter("E"."EMPNO"=7369)  
  
21 rows selected.  
    www.zzzyk.com  
<span style="color:#009900;">还可以用下面的方式获得SQL_ID和CHILD_NUMBER</span>  
  
SELECT /* TOTO *
Oracle
MySQL
Access
SQLServer
DB2
Excel
SQLite
SYBASE
Postgres
如果你遇到数据库难题:
请访问www.zzzyk.com 试试
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,