查看 sql 执行计划的方法有许多种, 10046 事件就是其中的一种. 与其他查看 sql 执行计划不同, 当我们遇到比较复杂的 sql 语句, 我们可以通过 10046 跟踪 sql 得到执行计划中每一个步骤的逻辑读, 物理读以及花费的时间等. 这种细粒度的跟踪对于我们分析 sql 性能尤其有用.

10046:SQL到底是如何执行的: 
10046 = 设置sql_trace=true; 10046 可以跟踪到等待事件&绑定变量;   tkprof 只解读(格式化)10046的trace文件
10053:SQL为什么要这样执行:
将语句执行涉及到的与成本相关的信息展示出来; 有表的各个index的成本的罗列(index的访问成本),罗列访问表的成本,展示为何是这个执行计划,10053使用的很少的。

10046事件:
> 跟踪会话执行的SQL的情况
> 跟踪会话中的SQL的执行计划及等待事件
> 可以通过TKPROF,TRCA等工具格式化trc文件

打开10046事件跟踪:
alter session set events = '10046 trace name context forever,level 12';

关闭10046事件跟踪:
alter session set events '10046 trace name context off';

dump 控制文件结构:
alter session set events 'immediate trace name controlf level 12';

dump 数据文件头:
alter session set events 'immediate trace name file_hdrs level 12';

10053事件:
优化器输入、计算输出的协议,把决策过程日志写入跟踪文件,可以看出优化器的工作原理,选择最佳执行计划的原因。
打开10053事件跟踪:
alter session set events '10053 trace name context forever,level 1';
获得跟踪文件的位置:
SQL> oradebug setmypid
SQL> oradebug tracefile_name
关闭10053事件跟踪:
alter session set events '10053 trace name context off';

event 10053跟踪文件的内容:
> 优化语句相关表的查询块和对象标识符
> 考虑到的查询转换
> 缩写名称的注释
> 绑定变量的结果
> 优化器考虑到的参数(显式和隐式)
> 系统统计信息
> 表和索引的对象统计信息
> 单表访问路径和成本
> 执行计划
> 谓语信息
> 查询块的outline信息

一般来说, 使用 10046 事件得到 sql 执行计划的步骤如下:
1. 激活当前 session 10046 事件
2. 在当前 session 中执行 sql 语句
3. 关闭当前 session 10046 事件

执行完上述步骤后, 通常会自动生成一个 trace 文件. 在 oracle 11g 中, trace 文件一般放在$ORACLE_BASE/diag/rdbms/{database_name}/$ORACLE_SID/trace 目录下. 如果使用 oradebug 激活跟踪 10046后, 可以使用 oradebug tracefile_name 得到刚刚生成的 trace 文件的完整路径.

  1. NAME                                 TYPE        VALUE
  2. ------------------------------------ ----------- ------------------------------
  3. background_dump_dest                 string      g:\app\davidd\diag\rdbms\david
  4. \david\trace

刚刚提到的 oradebug 激活跟踪 10046 事件, 我想大部分 dba 都会使用. oradebug 是个功能强大非常好用的工具, 使用 oradebug help 将会看到它的功能很多

  1. SQL> oradebug help

使用 oradebug 跟踪 10046 命令如下:

  1. SQL> oradebug setmypid
  2. Statement processed.
  3. // 激活 10046 事件
  4. SQL> oradebug event 10046 trace name context forever,level 12;
  5. Statement processed.
  6. SQL> select /*+ leading(t3) use_merge(t4) */ *
  7. 2  from t3, t4
  8. 3  where t3.id = t4.t3_id and t3.n = 1100;
  9. 10 rows selected.
  10. // 在当前 session 关闭 10046 事件
  11. SQL> oradebug event 10046 trace name context off;
  12. Statement processed.
  13. // 使用 oradebug tracefile_name 可以直接看到生成的 trace 文件的位置
  14. SQL> oradebug tracefile_name;
  15. g:\app\davidd\diag\rdbms\david\david\trace\david_ora_2176.trc

其中, 10046 按照收集信息的内容分为以下等级:

 Level 0  停用SQL跟踪,相当于SQL_TRACE=FALSE
 Level 1  标准SQL跟踪,相当于SQL_TRACE=TRUE
 Level 4  在level 1的基础上增加绑定变量的信息
 Level 8  在level 1的基础上增加等待事件的信息
 Level 12  在level 1的基础上增加绑定变量和等待事件的信息

分析读懂 trace 文件

现在我们打开 g:\app\davidd\diag\rdbms\david\david\trace\david_ora_2176.trc 看看生成的 trace 文件的内容

  1. <pre name="code" class="sql"><pre name="code" class="sql"><pre name="code" class="sql"><pre name="code" class="sql" style="font-size:14px;">PARSING IN CURSOR #22 len=92 dep=0 uid=0 oct=3 lid=0 tim=900460923321 hv=1624778336 ad='34671d90' sqlid='g0rdyg9hdh9m0'
  2. select /*+ leading(t3) use_merge(t4) */ *
  3. from t3, t4
  4. where t3.id = t4.t3_id and t3.n = 1100
  5. END OF STMT
  6. PARSE #22:c=0,e=10777,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=3831111046,tim=900460923319
  7. EXEC #22:c=0,e=29,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=3831111046,tim=900460923482
  8. WAIT #22: nam='SQL*Net message to client' ela= 2 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=900460923512
  9. FETCH #22:c=15625,e=23922,p=0,cr=119,cu=0,mis=0,r=1,dep=0,og=1,plh=3831111046,tim=900460947462
  10. WAIT #22: nam='SQL*Net message from client' ela= 221 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=900460947755
  11. WAIT #22: nam='SQL*Net message to client' ela= 2 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=900460947803
  12. FETCH #22:c=0,e=71,p=0,cr=0,cu=0,mis=0,r=9,dep=0,og=1,plh=3831111046,tim=900460947864
  13. STAT #22 id=1 cnt=10 pid=0 pos=1 obj=0 op='MERGE JOIN  (cr=119 pr=0 pw=0 time=28 us cost=193 size=1280 card=10)'
  14. STAT #22 id=2 cnt=1 pid=1 pos=1 obj=0 op='SORT JOIN (cr=15 pr=0 pw=0 time=0 us cost=6 size=63 card=1)'
  15. STAT #22 id=3 cnt=1 pid=2 pos=1 obj=83550 op='TABLE ACCESS FULL T3 (cr=15 pr=0 pw=0 time=0 us cost=5 size=63 card=1)'
  16. STAT #22 id=4 cnt=10 pid=1 pos=2 obj=0 op='SORT JOIN (cr=104 pr=0 pw=0 time=11 us cost=187 size=650000 card=10000)'
  17. STAT #22 id=5 cnt=10000 pid=4 pos=1 obj=83552 op='TABLE ACCESS FULL T4 (cr=104 pr=0 pw=0 time=8603 us cost=29 size=650000 card=10000)'

从上面的 trace 文件我们可以看出 sql 语句经过了 parse(解析) -> exec(执行) -> fetch(从游标中获取数据) 几个过程, 其中第一句说明了当前跟踪执行的 sql 语句的概况,比如使用游标号, sql 语句的长度, 递归深度等等基本信息:

  1. PARSING IN CURSOR #22 len=92 dep=0 uid=0 oct=3 lid=0 tim=900460923321 hv=1624778336 ad='34671d90' sqlid='g0rdyg9hdh9m0'
 cursor  cursor number
 len  sql 语句长度
 dep  sql 语句递归深度
 uid  user id
 oct  oracle command type
 lid  privilege user id
 tim  timestamp,时间戳
 hv  hash id
 ad  sql address 地址, 用在 v$sqltext
 sqlid  sql id

接着, 下面的语句说明了 sql 语句具体的执行过程以及每一个步骤消耗 CPU 的时间等性能指标

  1. PARSE #22:c=0,e=10777,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh=3831111046,tim=900460923319
  2. EXEC #22:c=0,e=29,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=3831111046,tim=900460923482
  3. FETCH #22:c=15625,e=23922,p=0,cr=119,cu=0,mis=0,r=1,dep=0,og=1,plh=3831111046,tim=900460947462
 c  CPU 消耗的时间
 e  Elapsed time 
 p  number of physical reads 物理读的次数
 cr  number of buffers retrieved for CR reads   逻辑读的数据块
 cu  number of buffers retrieved in current mode (current 模式读取的数据块)
 mis  cursor missed in the cache 库缓存中丢失的游标, 硬解析次数
 r  number of rows processed 处理的行数
 dep  递归深度
 og  optimizer mode 【1:all_rows, 2:first_rows, 3:rule, 4:choose】
 plh  plan hash value
 tim  timestamp 时间戳

以及执行过程中的发生的等待事件

  1. WAIT #22: nam='SQL*Net message to client' ela= 2 driver id=1111838976 #bytes=1 p3=0 obj#=-1 tim=900460923512
 nam  an event that we waited for 等待事件
 ela  此操作消耗的时间
 p3  block 块号
 trm  timestamp 时间戳

最后显示的是该游标的执行计划

  1. STAT #22 id=1 cnt=10 pid=0 pos=1 obj=0 op='MERGE JOIN  (cr=119 pr=0 pw=0 time=28 us cost=193 size=1280 card=10)'
  2. STAT #22 id=2 cnt=1 pid=1 pos=1 obj=0 op='SORT JOIN (cr=15 pr=0 pw=0 time=0 us cost=6 size=63 card=1)'
  3. STAT #22 id=3 cnt=1 pid=2 pos=1 obj=83550 op='TABLE ACCESS FULL T3 (cr=15 pr=0 pw=0 time=0 us cost=5 size=63 card=1)'
  4. STAT #22 id=4 cnt=10 pid=1 pos=2 obj=0 op='SORT JOIN (cr=104 pr=0 pw=0 time=11 us cost=187 size=650000 card=10000)'
  5. STAT #22 id=5 cnt=10000 pid=4 pos=1 obj=83552 op='TABLE ACCESS FULL T4 (cr=104 pr=0 pw=0 time=8603 us cost=29 size=650000 card=10000
 cnt  当前行源返回的行数
 pid  parent id of this row source 当前行源的父结点 id
 pos  position in explain plan 执行计划的位置
 obj  object id of row source (if this is a base object)
 op   the row source access operation

例如, 执行步骤 merge join 消耗的逻辑读为 119, 物理读为 0, 耗费的时间为 28 us, 成本 cost 193,返回 10 条记录

使用 tkprof 命令翻译 trace 文件

我们也可以使用 tkprof 命令对 trace 文件进行翻译,得到一个容易理解的 trace 汇总报表文件

  1. C:\Documents and Settings\davidd> tkprof g:\app\davidd\diag\rdbms\david\david\trace\david_ora_2176.trc d:\trace.trc
  2. TKPROF: Release 11.2.0.1.0 - Development on Thu Dec 18 18:51:44 2014
  3. Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.

tkprof 翻译的 trace 文件的汇总报表如下:

  1. Trace file: g:\app\davidd\diag\rdbms\david\david\trace\david_ora_2176.trc
  2. Sort options: default
  3. ********************************************************************************
  4. count    = number of times OCI procedure was executed
  5. cpu      = cpu time in seconds executing
  6. elapsed  = elapsed time in seconds executing
  7. disk     = number of physical reads of buffers from disk
  8. query    = number of buffers gotten for consistent read
  9. current  = number of buffers gotten in current mode (usually for update)
  10. rows     = number of rows processed by the fetch or execute call
  11. ********************************************************************************
  12. select /*+ leading(t3) use_merge(t4) */ *
  13. from t3, t4
  14. where t3.id = t4.t3_id and t3.n = 1100
  15. call     count       cpu    elapsed       disk      query    current        rows
  16. ------- ------  -------- ---------- ---------- ---------- ----------  ----------
  17. Parse        1      0.00       0.00          0          0          0           0
  18. Execute      1      0.00       0.00          0          0          0           0
  19. Fetch        2      0.00       0.00          0        119          0          10
  20. ------- ------  -------- ---------- ---------- ---------- ----------  ----------
  21. total        4      0.00       0.00          0        119          0          10
  22. Misses in library cache during parse: 1
  23. Optimizer mode: ALL_ROWS
  24. Parsing user id: SYS
  25. Rows     Row Source Operation
  26. -------  ---------------------------------------------------
  27. 10  MERGE JOIN  (cr=119 pr=0 pw=0 time=0 us cost=193 size=1280 card=10)
  28. 1   SORT JOIN (cr=15 pr=0 pw=0 time=0 us cost=6 size=63 card=1)
  29. 1    TABLE ACCESS FULL T3 (cr=15 pr=0 pw=0 time=0 us cost=5 size=63 card=1)
  30. 10   SORT JOIN (cr=104 pr=0 pw=0 time=0 us cost=187 size=650000 card=10000)
  31. 10000    TABLE ACCESS FULL T4 (cr=104 pr=0 pw=0 time=8733 us cost=29 size=650000 card=10000)
  32. Elapsed times include waiting on following events:
  33. Event waited on                             Times   Max. Wait  Total Waited
  34. ----------------------------------------   Waited  ----------  ------------
  35. SQL*Net message to client                       2        0.00          0.00
  36. SQL*Net message from client                     2       20.23         20.23
  37. ********************************************************************************
  38. OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
  39. call     count       cpu    elapsed       disk      query    current        rows
  40. ------- ------  -------- ---------- ---------- ---------- ----------  ----------
  41. Parse        1      0.00       0.00          0          0          0           0
  42. Execute      1      0.00       0.00          0          0          0           0
  43. Fetch        2      0.00       0.00          0        119          0          10
  44. ------- ------  -------- ---------- ---------- ---------- ----------  ----------
  45. total        4      0.00       0.00          0        119          0          10
  46. Misses in library cache during parse: 1
  47. Elapsed times include waiting on following events:
  48. Event waited on                             Times   Max. Wait  Total Waited
  49. ----------------------------------------   Waited  ----------  ------------
  50. SQL*Net message to client                       3        0.00          0.00
  51. SQL*Net message from client                     3       20.23         30.20
  52. OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
  53. call     count       cpu    elapsed       disk      query    current        rows
  54. ------- ------  -------- ---------- ---------- ---------- ----------  ----------
  55. Parse        0      0.00       0.00          0          0          0           0
  56. Execute      0      0.00       0.00          0          0          0           0
  57. Fetch        0      0.00       0.00          0          0          0           0
  58. ------- ------  -------- ---------- ---------- ---------- ----------  ----------
  59. total        0      0.00       0.00          0          0          0           0
  60. Misses in library cache during parse: 0
  61. 1  user  SQL statements in session.
  62. 0  internal SQL statements in session.
  63. 1  SQL statements in session.
  64. ********************************************************************************
  65. Trace file: g:\app\davidd\diag\rdbms\david\david\trace\david_ora_2176.trc
  66. Trace file compatibility: 11.1.0.7
  67. Sort options: default
  68. 1  session in tracefile.
  69. 1  user  SQL statements in trace file.
  70. 0  internal SQL statements in trace file.
  71. 1  SQL statements in trace file.
  72. 1  unique SQL statements in trace file.
  73. 122  lines in trace file.
  74. 0  elapsed seconds in trace file.

其中,Misses in library cache during parse :1   意思是解析的时候库缓存丢失游标,  也就是说发生了一次硬解析

参考: http://www.eygle.com/archives/2005/10/aeearaw_traceia.html

http://czmmiao.iteye.com/blog/1493765   tkprof 的使用

http://czmmiao.iteye.com/blog/1493933   读懂trace

10046事件sql_trace跟踪的更多相关文章

  1. Oracle SQL Trace 和 10046 事件

    http://blog.csdn.net/tianlesoftware/article/details/5857023 一. SQL_TRACE 当SQL语句出现性能问题时,我们可以用SQL_TRAC ...

  2. 在Oracle中利用SQL_TRACE跟踪SQL的执行

    当你在执行一条SQL语句非常慢的时候,你是不是想问Oracle怎么执行这条语句的呢? Oracle提供的SQL_TRACE工具可以让你知道你执行的SQL究竟做了什么.执行的过程会被 输出到trace文 ...

  3. SQL Tuning 基础概述03 - 使用sql_trace和10046事件跟踪执行计划

    1.使用sql_trace跟踪执行计划 1.1 当前session跟踪: alter session set sql_trace = true; //开始sql_trace alter session ...

  4. 10046事件跟踪会话sql

    背景知识: 10046 事件按照收集信息内容,可以分成4个级别: Level 1: 等同于SQL_TRACE 的功能 Level 4: 在Level 1的基础上增加收集绑定变量的信息 Level 8: ...

  5. Oracle执行语句跟踪(2)——使用10046事件实现语句追踪

    接上篇博文Oracle执行语句跟踪(1)--使用sql trace实现语句追踪,一旦我们通过会话追踪获取到超时事物的执行语句,就可以使用10046事件对语句进行追踪. 启用10046事件追踪的方式 S ...

  6. Oracle 课程八之性能优化之10046事件

    Oracle 的事件很多. 具体参考blog: Oracle 跟踪事件 set event 转摘:http://blog.csdn.net/tianlesoftware/archive/2009/12 ...

  7. 深入理解Oracle调试事件:10046事件详解

    10046事件是SQL_TRACE的扩展,被戏称为"吃了兴奋剂的SQL_TRACE"       有效的追踪级别:              ① 0级:SQL_TRACE=FASL ...

  8. 通过SQL Server的扩展事件来跟踪SQL语句在运行时,时间都消耗到哪儿了?

    原文:通过SQL Server的扩展事件来跟踪SQL语句在运行时,时间都消耗到哪儿了? 问题就是,一个很简单的语句,在不同的服务器上执行,所需要的时间相差很大,特别提到在性能差的服务器上反而快,在性能 ...

  9. 利用sql_trace跟踪一个指定会话的操作

    1.  sys用户给管理用户授权.SQL> grant execute on sys.dbms_system to andy;Grant succeeded.2. 查询被跟踪用户的sid,ser ...

随机推荐

  1. 批处理学习笔记3 - 变量声明和goto代替while循环

    批处理中没有while循环,只能用goto代替.下面是代码 @echo off set /a i = 0 :again echo %i% set /a i= %i% + 1 if %i% lss 10 ...

  2. 本地CS的导出xls代码段

    用到之前发的NPOI的那个工具类库 //导出private void btnExport_Click(object sender, EventArgs e){saveFileDialog1.ShowD ...

  3. atitit.ajax上传文件的实现原理 与设计

    atitit.ajax上传文件的实现原理 与设计 1. 上传文件的三大难题 1 1.1. 本地预览 1 1.2. 无刷新 1 1.3. 进度显示 1 2.  传统的html4  + ajax 是无法直 ...

  4. 一些常见的关于Linux系统的问题

    1 如何看当前Linux系统有几颗物理CPU和每颗CPU的核数? 答:[root@centos6 ~ 10:55 #35]# cat /proc/cpuinfo|grep -c 'physical i ...

  5. C++ 智能指针 shared_ptr

    今天晚上去旁听了C++高级编程的课,其中提到智能指针.第一反映还以为是auto_ptr呢,一听才知道是share_ptr这个.哦,原来是C++11特性.大致的原因是auto_ptr有一点缺陷,而sha ...

  6. GIS(一)——在js版搜索地图上加入Marker标记

    因为我们做的是有关于旅游方面的项目,所以涉及到了地图功能.我接到的当中一个任务就是,在地图上显示指定的几个景点,并在地图上加上标记. 我们项目用的是搜狗地图.使用的是js版本号.大家有兴趣的话,能够參 ...

  7. C++虚函数表与虚析构函数

    1.静态联编和动态联编联编:将源代码中的函数调用解释为要执行函数代码. 静态联编:编译时能确定唯一函数.在C中,每个函数名都能确定唯一的函数代码.在C++中,因为有函数重载,编译器须根据函数名,参数才 ...

  8. html5和css3学习历程

    1.video,audio视频和音频的应用 <!doctype html><html> <head></head> <body>  < ...

  9. Mybatis generator 自动生成代码

    开发项目的时候,表很多,是不可能一点点的自己去写xml ,dao文件的,这里就需要用到代码的自动生成工具了. 第一步:导入jar包,当然,这之前,基本环境,像mybatis,数据库之类的都得搭建好. ...

  10. 【iOS】TableView的footerView不随cell滚动而停留在tableView底部的问题

    苹果官方给我提供TableView的FooterView和HeaderView停留在顶部的非常不错效果,有时候我们不须要这些FooterView和HeaderView停留在底部或者上部,如今就以Foo ...