Oracle如何查看执行计划

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle如何查看执行计划相关的知识,希望对你有一定的参考价值。

一、通过PL/SQL Dev工具
1、直接File->New->Explain Plan Window,在窗口中执行sql可以查看计划结果。其中,Cost表示cpu的消耗,单位为n%,Cardinality表示执行的行数,等价Rows。
2、先执行 EXPLAIN PLAN FOR select * from tableA where paraA=1,再 select * from table(DBMS_XPLAN.DISPLAY)便可以看到oracle的执行计划了,看到的结果和1中的一样,所以使用工具的时候推荐使用1方法。
注意:PL/SQL Dev工具的Command window中不支持set autotrance on的命令。还有使用工具方法查看计划看到的信息不全,有些时候我们需要sqlplus的支持。

二、通过sqlplus
1.最简单的办法
Sql> set autotrace on
Sql> select * from dual;
执行完语句后,会显示explain plan 与 统计信息。
这个语句的优点就是它的缺点,这样在用该方法查看执行时间较长的sql语句时,需要等待该语句执行成功后,才返回执行计划,使优化的周期大大增长。如果不想执行语句而只是想得到执行计划可以采用:
Sql> set autotrace traceonly
这样,就只会列出执行计划,而不会真正的执行语句,大大减少了优化时间。虽然也列出了统计信息,但是因为没有执行语句,所以该统计信息没有用处,如果执行该语句时遇到错误,解决方法为:
(1)在要分析的用户下:
Sqlplus > @ ?
dbmsadminutlxplan.sql
(2) 用sys用户登陆
Sqlplus > @ ?sqlplusadminplustrce.sql
Sqlplus > grant plustrace to user_name;
- - user_name是上面所说的分析用户

2.用explain plan命令
(1) sqlplus > explain plan for select * from testdb.myuser
(2) sqlplus > select * from table(dbms_xplan.display);
上面这2种方法只能为在本会话中正在运行的语句产生执行计划,即我们需要已经知道了哪条语句运行的效率很差,我们是有目的只对这条SQL语句去优化。其实,在很多情况下,我们只会听一个客户抱怨说现在系统运行很慢,而我们不知道是哪个SQL引起的。此时有许多现成的语句可以找出耗费资源比较多的语句,如:
SELECT ADDRESS, substr(SQL_TEXT,1,20) Text, buffer_gets, executions,
buffer_gets/executions AVG FROM v$sqlarea
WHERE executions>0 AND buffer_gets > 100000 ORDER BY 5;
ADDRESS TEXT BUFFER_GETS EXECUTIONS AVG
-------- ---------------------------------------- ----------- ---------- ------------------------------------------------------------
66D83D64 select t.name, (sel 421531 60104 7.01336017
66D9E8AC select t.schema, t.n 1141739 2732 417.913250
66B82BCC select s.synonym_nam 441261 6 73543.5
从而对找出的语句进行进一步优化。当然我们还可以为一个正在运行的会话中运行的所有SQL语句生成执行计划,这需要对该会话进行跟踪,产生trace文件,然后对该文件用tkprof程序格式化一下,这种得到执行计划的方式很有用,因为它包含其它额外信息,如SQL语句执行的每个阶段(如Parse、Execute、Fetch)分别耗费的各个资源情况(如CPU、DISK、elapsed等)。

3、启用SQL_TRACE跟踪所有后台进程活动:
全局参数设置: .OracleHome/admin/SID/pfile中指定: SQL_TRACE = true (10g)
当前session中设置:
SQL> alter session set SQL_TRACE=true;
SQL> select * from dual;
SQL> alter session set SQL_TRACE=false;
对其他用户进行跟踪设置:
SQL> select sid,serial#,username from v$session where username='XXX';
SID SERIAL# USERNAME
------ ---------- ------------------
127 31923 A
128 54521 B
开启跟踪:SQL> exec dbms_system.set_SQL_TRACE_in_session(127,31923,true);
关闭跟踪:SQL> exec dbms_system.set_SQL_TRACE_in_session(127,31923,false);
然后使用oracle自带的tkprof命令行工具格式化跟踪文件。

4、使用10046事件进行查询:
10046事件级别:
Lv1 - 启用标准的SQL_TRACE功能,等价于SQL_TRACE
Lv4 - Level 1 + 绑定值(bind values)
Lv8 - Level 1 + 等待事件跟踪
Lv12 - Level 1 + Level 4 + Level 8
全局设定:
OracleHome/admin/SID/pfile中指定: EVENT="10046 trace name context forever,level 12"
当前session设定:
开启:SQL> alter session set events '10046 trace name context forever, level 8';
关闭:SQL> alter session set events '10046 trace name context off';
对其他用户进行设置:
SQL> select sid,serial#,username from v$session where username='XXX';
SID SERIAL# USERNAME
------ ---------- ------------------
127 31923 A

SQL> exec dbms_system.set_ev(127,31923,10046,8,'A');

5、使用tkprof格式化跟踪文件: (根据下面SQL语句得到的文件都不存在该目录下,郁闷啊,懵懂啊...)

一般,一次跟踪可以分为以下几步:
1、界定需要跟踪的目标范围,并使用适当的命令启用所需跟踪。
2、经过一段时间后,停止跟踪。此时应该产生了一个跟踪结果文件。
3、找到跟踪文件,并对其进行格式化,然后阅读或分析。

--使用一下SQL找到当前session的跟踪文件:
SELECT d.value|| '/' ||lower(rtrim(i.instance, chr( 0 )))|| '_ora_' ||p.spid|| '.trc' trace_file_name
from
( select p.spid from v$mystat m,v$session s, v$process p
where m.statistic# = 1 and s.sid = m.sid and p.addr = s.paddr) p,
( select t.instance from v$thread t,v$parameter v
where v.name = 'thread' and (v.value = 0 or t.thread# = to_number(v.value))) i,
( select value from v$parameter where name = 'user_dump_dest' ) d;
-- 其它用户的 session
SELECT d.value|| '/' ||lower(rtrim(i.instance, chr( 0 )))|| '_ora_' ||p.spid|| '.trc' trace_file_name
from
( select p.spid from v$session s, v$process p
where s.sid= '27' and s. SERIAL#= '30' and p.addr = s.paddr) p,
( select t.instance from v$thread t,v$parameter v
where v.name = 'thread' and (v.value = 0 or t.thread# = to_number(v.value))) i,
( select value from v$parameter where name = 'user_dump_dest' ) d;

--查找后使用tkprof命令,将TRACE文件格式为到D盘的explain_format.txt文件中
SQL> $tkprof d:/oracle/admin/FZLGFM/udump/fzlgfm_ora_3468.trc d:/explain_format.txt

文件内容大致如下(看不太懂....懵懂啊.....天啊....神啊.....过几时就懂了/////////////)
TKPROF: Release 9.2.0.1.0 - Production on 星期二 4月 20 13:59:20 2010
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
Trace file: d:/oracle/admin/FZLGFM/udump/fzlgfm_ora_3468.trc
Sort options: default
********************************************************************************
count = number of times OCI procedure was executed
cpu = cpu time in seconds executing
elapsed = elapsed time in seconds executing
disk = number of physical reads of buffers from disk
query = number of buffers gotten for consistent read
current = number of buffers gotten in current mode (usually for update)
rows = number of rows processed by the fetch or execute call
********************************************************************************
alter session set events '10046 trace name context forever, level 8'

call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 0 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 1 0.00 0.00 0 0 0 0

Misses in library cache during parse: 0
Misses in library cache during execute: 1
Optimizer goal: CHOOSE
Parsing user id: SYS
参考技术A 1、直接File->New->Explain Plan Window,在窗口中执行sql可以查看计划结果。其中,Cost表示cpu的消耗,单位为n%,Cardinality表示执行的行数,等价Rows。
2、先执行 EXPLAIN PLAN FOR select * from tableA where paraA=1,再 select * from table(DBMS_XPLAN.DISPLAY)便可以看到oracle的执行计划了,看到的结果和1中的一样,所以使用工具的时候推荐使用1方法。
注意:PL/SQL Dev工具的Command window中不支持set autotrance on的命令。还有使用工具方法查看计划看到的信息不全,有些时候我们需要sqlplus的支持。

二、通过sqlplus
1.最简单的办法
Sql> set autotrace on
Sql> select * from dual;
执行完语句后,会显示explain plan 与 统计信息。
这个语句的优点就是它的缺点,这样在用该方法查看执行时间较长的sql语句时,需要等待该语句执行成功后,才返回执行计划,使优化的周期大大增长。如果不想执行语句而只是想得到执行计划可以采用:
Sql> set autotrace traceonly
参考技术B plsql developer的话,在sql命令窗口中,按F5就能看到执行计划
sqlplus的话:
方法一
第一步:登入sql/plus 执行命令(无先后顺序)
set time on; (说明:打开时间显示)
set autotrace on; (说明:打开自动分析统计,并显示SQL语句的运行结果)
set autotrace traceonly; (说明:打开自动分析统计,不显示SQL语句的运行结果)
二者选一个执行
第二步: 输入你要查看的sql 执行
第三步:查看结果 如图 (图怎么沾不上啊)
方法二
先执行 EXPLAIN PLAN FOR select * from G_GAMBLING gamb where gamb.active=1
再 select * from table(DBMS_XPLAN.DISPLAY)便可以看到oracle的执行计划了
参考技术C 1、直接File->New->Explain Plan Window,在窗口中执行sql可以查看计划结果。其中,Cost表示cpu的消耗,单位为n%,Cardinality表示执行的行数,等价Rows。
2、先执行 EXPLAIN PLAN FOR select * from tableA where paraA=1,再 select * from table(DBMS_XPLAN.DISPLAY)便可以看到oracle的执行计划了,看到的结果和1中的一样,所以使用工具的时候推荐使用1方法。
参考技术D

1、登录PLSQL Developer工具:

2、在sql Windows窗口输入sql语句,按F5就可以看见执行计划了。

oracle如何查看执行计划

1.在PL/SQL Developer中得到一个SQL的执行计划
输入想要查看执行计划的目标SQL,再按一下快捷键F5就可以了。
2.explain plan 命令
explain plan for + 目标SQL
select * from table(dbms_xplan.display)
3. DBMS_XPLAN 包
1) select * from table(dbms_xplan.display_cursor(null,null,‘advanced‘))
它用于在SQLPLUS中查看刚刚执行过的SQL的执行计划。这里所传入的第一个和第二个参数的值均为null,第三个参数的值是 advanced,
第三个输入参数的值也可以是 all,只不过用 advanced 后的显示结果会比用 all 的显示结果更详细一些。
2) select * from table(dbms_xplan.display_cursor(‘sql_id/hash_value‘,child_cursor_number,‘advanced‘))
它用于查看指定SQL的执行计划。这里所传入的第一个参数的值是指定SQL的SQL ID 或者 SQL HASH VALUE,第二个参数的值是要查看的
执行计划所在的Child Cursor Number,第三个参数和上边的介绍一样,我们一般都是用 advanced
只要目标SQL所对应的Child Cursor还在Library Cache中,我们就可以从 V$SQL 中查询到目标SQL的Child Cursor的详细信息,包括
SQL ID、SQL HASH VALUE、Child Cursor Number等。
select sql_text,sql_id,hash_value,child_number from v$sql where sql_text like ‘SQL目标语句‘;
只要目标SQL的执行计划所在的Child Cursor还没有被age out 出 Shared Pool,就可以使用该方法来查看该SQL的执行计划。
3) select * from table(dbms_xplan.display_awr(‘sql_id‘))
它用于查看指定SQL的所有历史执行计划。使用方法1),2)能够显示目标SQL执行计划的前提是该SQL的执行计划还在Shared Pool中,而如果
该SQL的执行计划已经被 age out 出 Shared Pool,那么只要该SQL的执行计划被Oracle采集到AWR Repository中,我们就可以使用该方法来查
看该SQL的所有历史执行计划。
手工采集AWR报告的方法:exec dbms_workload_repository.create_snapshot();
查看目标SQL的执行计划是否被 age out 出 Shared Pool: select sql_text,sql_id,version_count,executions from v$sqlarea where
sql_text like ‘目标SQL‘;
清空Shared Pool:alter system flush shared_pool;(请勿随意在生产环境执行此语句)
4. AUTOTRACE 开关
set autotrace [off | on | traceonly]
1) 在SQLPLUS的当前Session中执行命令 set autotrace on, 可以在当前Session中将autotrace开关完全打开。这样,在这个Session中随后
执行的所有SQL语句,除了显示SQL执行结果之外,还会额外显示这些SQL所对应的执行计划和资源消耗情况。
2) 在SQLPLUS的当前Session中执行命令 set autotrace off, 可以在当前Session中将autotrace开关关闭,这样,在这个Session中随后执行
的所有SQL都只会显示SQL执行结果。autotrace开关的默认值是off.
3) 在SQLPLUS的当前Session中执行命令 set autotrace traceonly, 可以在当前Session中将autotrace开关以不显示SQL执行结果的具体内容
的方式打开。适用于那些SQL执行结果的具体内容特别长,会连续刷屏的SQL, 这种情况下我们不关心SQL的执行结果,而只是关系SQL的执行计划
和资源消耗量。
5. 10046事件与 tkprof命令(得到的执行计划最准确)
这种方法可以得到执行计划中每一个执行步骤所消耗的逻辑读、物理读和花费的时间。
1) oradebug setmypid
表示准备对当前Session使用oradebug命令。
2) oradebug event 10046 trace name context forever,level 12
在当前Session中激活10046事件。
3) 执行目标SQL
4) oradebug tracefile_name
显示当前Session激活10046事件后所对应的trace文件的路径和名称。
5) oradebug event 10046 trace name context off
在当前Session中关闭10046事件。
6) tkprof trace文件绝对路径 翻译后目标文件的绝对路径
使用tkprof命令翻译trace文件,使结果更直观。
6.(得到真实的、准确的执行计划) 如果目标SQL的执行计划还在Shared Pool中,可以使用脚本display_cursor-9i.sql和存储过程printsql来得到其真实的执行计划和资源消耗情况。如果目标SQL的执行计划已经被age out 出 Shared Pool了,我们可以执行DBMS_XPLAN.DISPLAY_AWR 或者使用 AWR SQL 报告和 Statspack SQL 报告来得到其历史执行计划和资源消耗。
1) display_cursor_9i.sql的用法(适用于Oracle 9i 及其以后的数据库版本)
在执行脚本时,传入待查看执行计划的目标SQL的SQL HASH VALUE 和 Child Cursor Number
a. 执行目标SQL
b. 查询HASH_VALUE 和 Child Number
select sql_text,hash_value,child_number from v$sql where sql_text like ‘目标SQL‘;
c. 执行脚本
@脚本 HASH_VALUE CHILD_NUMBER
2) printsql的用法(适用于9i/10g/11g)
存储过程printsql是在脚本display_cursor_9i.sql上的封装,它可以把指定SPID或者Session ID的进程或者Session 正在执行的SQL以及其对应的真实执行计划、资源消耗情况打印出来。
a. 执行 topas
得到oracle的PID
b. set serveroutput on size 1000000
c. exec printsql(PID,‘SPID‘)
注释:PID是a查询出来的PID,‘SPID‘原样输入。
3) 获取AWR SQL 报告(10g及其以后的版本)
手工执行脚本 $ORACLE_HOME/rdbms/admin/awrsqrpt.sql,并依此输入报告类型(text/html)、要查看的快照范围(最近几天内的快照)、目标SQL ID和所要生产的AWR SQL 报告的名称。
4) 获取Statspack SQL 报告(9i)
手工执行脚本 $ORACLE_HOME/rdbms/admin/sprepsql,并依此输入要查看的快照的范围、目标SQL HASH VALUE 和所要生成的Statspack SQL报告的名称。
注释:事先已经部署了Statspack报告,并且采集Statspack报告的level值大于等于6(Statspack 报告level的默认值是5)

7.如何查看执行计划的执行顺序
先从最开头一直连续往右看,直到看到最右边的并列的地方;对于不并列的,靠右的先执行;如果见到并列的,从上往下看,对于并列的部分,靠上的先执行。





































































以上是关于Oracle如何查看执行计划的主要内容,如果未能解决你的问题,请参考以下文章

如何查看Oracle中sql语句的执行时间

oracle如何查看执行计划

如何在 SQuirrel SQL 中查看 Oracle 执行计划?

在Oracle中启用AutoTrace查看SQL执行计划

Oracle执行计划

如何解析oracle执行计划