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

一般来说, 使用 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
  2. HELP           [command]                        Describe one or all commands
  3. SETMYPID                                        Debug current process
  4. SETOSPID       <ospid>                        Set OS pid of process to debug
  5. SETORAPID      <orapid> ['force']             Set Oracle pid of process to debug
  6. SETORAPNAME    <orapname>                     Set Oracle process name to debug
  7. SHORT_STACK                                     Get abridged OS stack
  8. CURRENT_SQL                                     Get current SQL
  9. DUMP           <dump_name> <lvl> [addr]         Invoke named dump
  10. DUMPSGA        [bytes]                          Dump fixed SGA
  11. DUMPLIST                                        Print a list of available dumps
  12. EVENT          <text>                         Set trace event in process
  13. SESSION_EVENT  <text>                         Set trace event in session
  14. DUMPVAR        <p|s|uga> <name> [level]         Print/dump a fixed PGA/SGA/UGA variable
  15. DUMPTYPE       <address> <type> <count>       Print/dump an address with type info
  16. SETVAR         <p|s|uga> <name> <value>       Modify a fixed PGA/SGA/UGA variable
  17. PEEK           <addr> <len> [level]             Print/Dump memory
  18. POKE           <addr> <len> <value>           Modify memory
  19. WAKEUP         <orapid>                       Wake up Oracle process
  20. SUSPEND                                         Suspend execution
  21. RESUME                                          Resume execution
  22. FLUSH                                           Flush pending writes to trace file
  23. CLOSE_TRACE                                     Close trace file
  24. TRACEFILE_NAME                                  Get name of trace file
  25. LKDEBUG                                         Invoke global enqueue service debugger
  26. NSDBX                                           Invoke CGS name-service debugger
  27. -G             <Inst-List | def | all>        Parallel oradebug command prefix
  28. -R             <Inst-List | def | all>        Parallel oradebug prefix (return output
  29. SETINST        <instance# .. | all>           Set instance list in double quotes
  30. SGATOFILE      <SGA dump dir>                 Dump SGA to file; dirname in double quotes
  31. DMPCOWSGA      <SGA dump dir>                 Dump & map SGA as COW; dirname in double quotes
  32. MAPCOWSGA      <SGA dump dir>                 Map SGA as COW; dirname in double quotes
  33. HANGANALYZE    [level] [syslevel]               Analyze system hang
  34. FFBEGIN                                         Flash Freeze the Instance
  35. FFDEREGISTER                                    FF deregister instance from cluster
  36. FFTERMINST                                      Call exit and terminate instance
  37. FFRESUMEINST                                    Resume the flash frozen instance
  38. FFSTATUS                                        Flash freeze status of instance
  39. SKDSTTPCS      <ifname>  <ofname>               Helps translate PCs to names
  40. WATCH          <address> <len> <self|exist|all|target>  Watch a region of memory
  41. DELETE         <local|global|target> watchpoint <id>    Delete a watchpoint
  42. SHOW           <local|global|target> watchpoints        Show  watchpoints
  43. DIRECT_ACCESS  <set/enable/disable command | select query> Fixed table access
  44. CORE                                            Dump core without crashing process
  45. IPC                                             Dump ipc information
  46. UNLIMIT                                         Unlimit the size of the trace file
  47. PROCSTAT                                        Dump process statistics
  48. CALL           <func> [arg1] ... [argn]       Invoke function with arguments

使用 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   意思是解析的时候库缓存丢失游标,  也就是说发生了一次硬解析

使用 10046 查看执行计划并读懂 trace 文件的更多相关文章

  1. Oracle数据库查看执行计划

    基于ORACLE的应用系统很多性能问题,是由应用系统SQL性能低劣引起的,所以,SQL的性能优化很重要,分析与优化SQL的性能我们一般通过查看该SQL的执行计划,本文就如何看懂执行计划,以及如何通过分 ...

  2. ORACLE数据库查看执行计划的方法

    一.什么是执行计划(explain plan) 执行计划:一条查询语句在ORACLE中的执行过程或访问路径的描述. 二.如何查看执行计划 1: 在PL/SQL下按F5查看执行计划.第三方工具toad等 ...

  3. oracle如何查看执行计划

    1.在PL/SQL Developer中得到一个SQL的执行计划 输入想要查看执行计划的目标SQL,再按一下快捷键F5就可以了.2.explain plan 命令 explain plan for + ...

  4. oracle执行计划(二)----如何查看执行计划

    目录: (一)六种执行计划  (1)explain plan for  (2)set autotrace on  (3)statistics_level=all  (4)dbms_xplan.disp ...

  5. oracle查看执行计划以及使用场景

    文档结构: oracle执行计划使用场景 环境: Centos 6.10 Oracle 18.3.0.0.0 c 11g默认启动了自动统计信息收集的任务,默认运行时间是周一到周五晚上10点和周6,周天 ...

  6. Mysql查看执行计划-explain

    最近生产环境有一些查询较慢,需要优化,于是先进行业务确认查询条件是否可以优化,不行再进行sql优化,于是学习了下Mysql查看执行计划. 语法 explain <sql语句>  例如: e ...

  7. MySQL 使用explain查看执行计划

    使用explain查看执行计划, 下面是针对这两条语句进行分析,其查询结果是一样的. EXPLAIN select n.id,n.title from info n inner join info_t ...

  8. T-SQL备忘(5):查看执行计划

    先理解几个概念:表扫描.聚集索引扫描.聚集索引查找.索引扫描.书签查找. [查看执行计划] 在理解概念之前先得知道如何查看执行计划—Ctrl+L.如下图: 注:SQL Server的执行计划是从右向左 ...

  9. sqlserver授予用户查看执行计划的权限

    sqlserver查看语句的执行计划是非常重要的,可以提高开发人员代码的质量.所以有必要授予开发人员对数据库查看执行计划的权限.   查看执行计划的权限属于数据库一级别的权限,具体例子如下   use ...

随机推荐

  1. anaconda指定镜像源,解决conda下载速度慢失败问题

    conda升级默认官网地址,速度会特别慢,现在我们指定一个当前可用的镜像,步骤如下: 1.执行命令,生成.condarc文件 conda config --add channels https://m ...

  2. 分析并实现 360 P1路由器上的测速功能(也可以针对金山测速功能)

    现在各种智能路由器以及一些PC上的防火墙软件,都提供网络测速功能.笔者对此进行了研究,并在自己的路由器上也实现了此功能.下面做一下总结 一般的网络测速,主要关注两个方面:网络延迟和下载速率 1.网络延 ...

  3. HBase学习笔记——配置及Shell操作

    1.HBase的配置 还是以前配置的集群,见:http://www.cnblogs.com/DarrenChan/p/6493373.html 我们约定:weekend03和weekend04放HMa ...

  4. sds(简单动态字符串) 内存预分配优化策略

    * 1024 , 也就是说. 当大小小于 1MB 的字符串运行追加操作时,sdsMakeRoomFor 就为它们分配多于所需大小一倍的空间: 当字符串的大小大于 1MB . 那么 sdsMakeRoo ...

  5. android webview处理h5打开本地文件浏览器的功能

    这周遇到一个比较棘手的问题,需要在android上边集成h5页面,并且在h5页面上,需要用户能够上传android本地的照片,一开始我以为webview会自动处理掉的,因此没太留意,当真正集成时,才发 ...

  6. R语言安装openxl包报错解决办法

    在R语言中使用openxlsx包,会报错 解决办法就是: 下载安装Set-Rtool,安装时注意勾选对话框 然后在R中运行以下代码: Sys.setenv("R_ZIPCMD" = ...

  7. nodejs操作图片方法

    最近项目中用到nodejs做图片服务器,用户上传图片生成缩略图返回地址一系列操作. 原来一直用.net平台,所有都封装好了生成缩略图这种分分钟就解决了,遂度娘一番全是调用imagemagick和gra ...

  8. 第二百二十六节,jQuery EasyUI,Tree(树)组件

    jQuery EasyUI,Tree(树)组件 本节课重点了解 EasyUI 中 Tree(树)组件的使用方法,这个组件依赖于 Draggable(拖 动)和 Droppable(放置)组件. 一.加 ...

  9. 你很熟悉CSS,却没掌握这些CSS技巧

    转载来自 http://www.html5cn.org/article-9294-1.html 做前端开发的人都很熟悉CSS,一个漂亮的网页由HTML标签和控制这些标签布局的CSS组成,因此CSS在开 ...

  10. jstat 监控调整GC很好用

    jstat命令使用 jstat命令可以查看堆内存各部分的使用量,以及加载类的数量.命令的格式如下: jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数] 注意:使用的jdk版本是 ...