常见的获取执行计划的方法

下面是几种常规的获取执行计划的方法。SQL TRACE、10046、10053 见后文。

方法获取步骤优缺点应用场景
explain plan for步骤1:explain plan for 跟上你要执行的SQL;
步骤2: select * from table(dbms_xplan.display(FORMAT=>'ADVANCED-PROJECTION')); (显示 v$sql_plan 视图中的语句的执行计划,也可以不带参数,该参数可以显示 outline data 等更详细的信息)
1.无需真正执行,快捷方便
2.没有输出运行时的相关统计信息(逻辑读,物理读,递归调用次数等);
3.无法判断处理了多少行以及表被访问了多少次;
如果某SQL执行很长时间才出结果或返回不了结果
dbms_xplan
(真的计划)
select * from table(dbms_xplan.display_cursor('&sq_id')); (从共享池里得到)
select * from table(dbms_xplan.display_awr('&sq_id')); (从AWR性能视图里得到)
1.知道sql_id立即可得到执行计划(并且是真实的执行计划),无需执行;
2.没有输出运行时的相关统计信息(逻辑读,物理读,递归调用次数等);
3.无法判断处理了多少行以及表被访问了多少次
观察某条SQL有多条执行计划的情况
statistics_level=all
(真的计划)
步骤1:alter session set statistics_level=all ;
步骤2:在此处执行你的SQL
步骤3:select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
1.必须要等到语句真正执行完毕后,才可以出结果,且无法控制输出记录展现与否。
2.可以清晰地从STARTS得出表被访问多少次;
3.可以清晰的从E-ROWS和A-ROWS中得到预测的行数和真实的行数,从而可以准确判断Oracle评估是否准确。
4.A-Time为每一步实际执行的时间,根据这一行可以知道该SQL耗时在哪儿。
5.虽然没有专门的输出运行时的相关统计信息(物理读,递归调用次数),但是执行计划中的BUFFERS就是真实的逻辑读的数值。
要想获取表被访问的次数,只能使用该方法
set autotrace on
(从 plan_table 中调的,假的计划)
步骤1:set autotrace xxx
步骤2:在此处执行你的SQL
1.可以输出运行时的相关统计信息(逻辑读,物理读,递归调用次数等);
2.必须要等语句执行完毕后才可以输出执行计划,但是可以控制输出内容;
3.无法看到表被访问了多少次
想粗略知道recursive calls递归调用次数的方法用这个,详细用 10046 trace 方法
awrsqrpt.sql步骤1:@?/rdbms/admin/awrsqrpt.sql
步骤2:选择你要的断点(begin snap 和end snap)
步骤3:输入你的sql_id
可以方便地看到多个执行计划想观察某条SQL多执行计划用该方法

SQL*Trace

追踪当前会话:

SQL> alter session set sql_trace=true;
-- <execute your sql statement>
SQL> alter session set sql_trace=false;

或者:
SQL> exec dbms_session.set_sql_trace(true);
-- <execute your sql statement>
SQL> exec dbms_session.set_sql_trace(false);

追踪其它会话:

exec sys.dhns_system.SET_SQL_TRACE_IN_SESSION(229,1263,TRUE);

实例级跟踪:
将参数 sql_trace 设置为 true 即可。

10046 事件

通过10046事件可以查看到如下信息:

1.可以看出SQL语句对应的等待事件
2.如果SQL语句中有函数调用,SQL中有SQL,都将会被列出,无处遁形;
3.如果SQL中含函数,函数中又套SQL等,即存在多层调用,想准确分析只能用该方法
4.可以方便的看出处理的行数,产生的物理逻辑读;
5.可以方便地看出解析时间和执行时间;
6.可以跟踪整个程序包
7.无法判断表被访问了多少次;
8.执行计划中的谓词部分不能清晰的展现出来

当前会话追踪 10046 事件:

alter session set tracefile_identifier='10046'; 
alter session set timed_statistics = true; 
alter session set statistics_level=all; 
alter session set max_dump_file_size = unlimited; 
alter session set events '10046 trace name context forever,level 12'; 
-- <execute your sql statement>
alter session set events '10046 trace name context off'; 

收集10046 trace可能会生成较大的trace file,可能会对性能有一定的影响。如果您的数据库对此比较敏感,请在业务比较空闲的时间收集。

Level 1 等同于SQL_TRACE的功能。
Level 4 在 Level 1 的基础上增加收集绑定变量的信息。
Level 8 在 Level 1 的基础上增加等待事件的信息
Level 12 等同于 Level4+Level8,即同时收集绑定变量信息和等待时间信息。

跟踪其它会话:
dbms_system.set_ev(sid,serial#,10046,0,'username');

10053 事件

当 set auotrace 或者 explain 显示执行计划错误而又找不到原因的时候。可以使用 10053 事件生成 trace 文件,以分析执行计划的生成过程,比如实例当时的参数值是什么,使用的统计信息值是什么,怎样计算的全表扫描和走索引的cost,各种join对应的cost等。

trace 文件中的内容有如下几个部分:

  • 参数区
  • SQL区
  • 系统信息区--SYSTEM STATISTICS INFORMATION
  • 基本统计信息--BASE STATISTICAL INFORMATION
  • 数据访问---ACCESS PATH
  • 关联查询----JOIN ORDER
  • 代价的最后修正
  • 最终执行计划

当前会话追踪 10053 事件:

alter session set tracefile_identifier='10053'; 
alter session set timed_statistics = true; 
alter session set statistics_level=all; 
alter session set max_dump_file_size = unlimited; 
alter session set events '10053 trace name context forever, level 1';

对其它会话执行 10053 事件:

exec sys.dbms_system.set_ev(<sid>,<serial#>,10053,{1|2|0},'');

注意:1和2表示打开事件,1的信息更全,0表示关闭

在分析 10053 trace 文件时,我们要关心统计信息是否准确以及各cost值的比较(cost是oracle衡量代价的一个数值,目前,Oracle并没有公布cost的计算方法)。

tkprof

trace 文件晦涩难懂,可以使用 tkprof 也格式化以帮助理解。
最简单地使用方法就是 tkprof tracefile outfile,该命令还支持其它参数,直接执行该命令可以查看帮助。

-- By 许望(RHCA、OCM、VCP)
最后修改:2020 年 05 月 26 日 09 : 13 AM
如果觉得我的文章对你有用,请随意赞赏