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