经典10046剖析案例-1

4. 10046事件

通过10046事件也可以查看目标SQL的执行计划。像10046这种事件,都不是Oracle官方文档中可以查询到的,这些事件一般用于调试目的,因此往往可以使用他们找到问题更详细的信息。

10046事件和之前的explain plan、DBMS_XPLAN包以及AUTOTRACE 开关的区别在于,10046事件产生的trc文件中明确显示了目标SQL实际执行计划中每一步所消耗的逻辑读、物理读和花费的时间,执行计划的成本分析, 进而可以看出为什么Oracle对于SQL选择了这样的执行计划,而不是那样的执行计划,之所以说是实际的执行计划,从10046事件执行的过程就可以看 出来:

(a)
在当前session激活10046事件。

(b)
在此session中执行SQL。

(c)
关闭此session的10046事件。

真正执行的SQL,对应的执行计划可以在trc文件中找到。这个trc文件会记录SQL的执行计划和资源消耗,命名格式“实例名_ora_当前session的spid.trc”。

(1).
激活10046事件

有两种方法

(a)
alter session set events ‘10046 trace name context forever, level 12‘;

(b)
oradebug setmypid/oradebug
setospid SPID;

oradebug event
10046 trace name context forever, level 12;

(2). 查看10046产生的trc文件名和路径的方法

(a) show parameter USER_DUMP_DEST显示trc文件存储的路径 -> 查找对应当前session的trc文件(若当前是单用户,则是最新产生的文件)。

实验:

(b)
使用上述(b)的ordebug产生trc文件,可以用oradebug tracefile_name得到trc文件名和路径。

oradebug有很多需要说的,首先这是sqlplus特有的命令,在PLSQL Developer中执行会提示无效的SQL语句,例如:

其次它是sysdba角色的命令,使用非sysdba执行会提示ORA-01031权限不足,例如:

使用sysdba登录后,可以查看oradebug的帮助:

尽管oradebug用的时候需要使用sysdba登录,看似有些麻烦,但和第一种alter session的方法相比,最大的好处就是alter session只能针对当前会话或系统级,即alter session或alter system设置,如果设置非本会话的跟踪,此时就可以用oradebug了,(据说dbms_system、dbms_monitor和dbms_support也可以实现相同的需求,但没有试过)。

使用oradebug设置10046事件之前需要首先设置待跟踪的会话:

(a)
跟踪本会话,使用:oradebug setmypid即可。

(b)
跟踪非本会话,使用:oradebug setospid
SPID
(来自v$process)。

查找SPID的方法

(a)
select * from v$session a where audsid = userenv(‘sessionid‘);返回SID值。

(b)
select s.USERNAME,

s.OSUSER,

s.SID,

s.PADDR,

s.PROCESS,

p.spid     os_process_id,

p.pid      oracle_process_id

from
v$session s, v$process p

where
s.paddr = p.addr

and
s.username = upper(‘待跟踪session用户名‘)

and
s.SID = (a)返回的SID;

例如:

其中:

v$process中的SPID是指操作系统的进程,即操作系统的PID

v$session中的pid, serial#是oracle分配的PID

此时如果需要跟踪24061这个session执行的SQL,可以用oradebug setospid
24061,然后oradebug event 10046 trace name context forever, level 12;就打开了10046事件。

接着可以通过oradebug tracefile_name查看trace文件名和路径,例如:

看下petest_ora_22756.trc的内容:

除了机器、实例、进程等基本信息外,真正写入的内容:

Received
ORADEBUG command ‘tracefile_name‘ from process Unix process pid: 22235, image:

表示接收到来自Unix的操作系统进程PID是22235的ORADEBUG命令,参数tracefile_name。

显然22235这个进程是sqlplus登陆后执行ORADEBUG的客户端,例如:

(3). 关闭10046的方法

(a) alter
session set events ‘10046 trace name context off‘;

(b)
oradebug event 10046 trace name context off;

分别对应两种打开10046事件的方法。

(4). 再说说oradebug和alter session打开10046事件产生trace文件的区别

(a) 使用alter session打开10046事件时,如果未执行SQL,则不会产生trace文件

(b) 使用oradebug event 10046
trace name context forever, level 12;打开10046事件,此时就已经产生trace文件,除基本信息外,主要是一行:

WAIT #0:
nam=‘SQL*Net message to client‘ ela= 2 driver id=1650815232 #bytes=1 p3=0
obj#=-1 tim=1379395297285576

当使用oradebug event 10046 trace name context off;关闭10046事件,会写入一行:

WAIT #0:
nam=‘SQL*Net message from client‘ ela= 30946429 driver id=1650815232 #bytes=1
p3=0 obj#=-1 tim=1379395328232564

(5). trace跟踪文件

上面说了打开和关闭10046的两种常用方法,下面简单看看trace文件都包含了什么,为什么说10046这种事件是用于调试的,我现在不能精通所有内容,大概谈谈理解。

首先执行命令打开10046事件、执行SQL、关闭10046事件,例如:

查看产生的trace文件:

两个"============"之前的内容,是执行SQL产生的信息,之前和之后的内容,应该是打开和关闭10046事件的信息。

红线框内的是这条SQL用的执行计划,从文件中看,一共有5步,括号内的是相关消耗

执行计划第一步:MERGE JOIN,逻辑读(cr)是11,物理读(pr)是0,时间(time)是378微秒。

执行计划第二步:TABLE ACCESS BY INDEX ROWID TEST1,逻辑读(cr)是4,物理读(pr)是0,时间(time)是139微秒。

执行计划第三步:INDEX FULL SCAN SYS_C0016790,逻辑读(cr)是2,物理读(pr)是0,时间(time)是86微秒。

执行计划第四步:SORT JOIN,逻辑读(cr)是7,物理读(pr)是0,时间(time)是266微秒。

执行计划第五步:TABLE ACCESS FULL TEST2,逻辑读(cr)是7,物理读(pr)是0,时间(time)是128微秒。

这里trc文件是一种裸trace文件,内容可看,但不是那么直观,可以使用tkprof命令翻译trc文件。例如:

查看生成的tkprof文件:

从这里可以更清楚地看到每步执行计划返回的行数,以及顺序关系,按照@dbsnake的执行计划读取口诀: “先从最开头一直连续往右看,直到看到最右边的并列的地方;对于不并列的,靠右的先执行;如果见到并列的,就从上往下看,对于并列的部分,靠上的先执行。简单分析下:

(a) INDEX FULL ...

先使用SYS_C0016790主键索引进行索引快速全扫描,这里SYS_C0016790是TEST1的主键,即t1id列。

(b) TABLE
ACCESS FULL ...

全表扫描TEST2表。

(c) TABLE ACCESS
BY ...

根据TEST1主键索引返回的ROWID,查询对应数据项。产生结果集1。

(d) SORT
JOIN

按照TEST2的t2id列排序。产生结果集2。

(e) MERGE JOIN

遍历结果集1,即取出结果集1的第1条记录,和结果集2中按照t1.t1id=t2.t2id的条件判断是否存在匹配记录,再取出结果集1的第2条记录继续判断,直到遍历完成结果集1。

这里用到的是“排序合并连接”,执行计划中对应的关键字是“MERGE JOIN”和“SORT
JOIN”,正常来讲,两个表第二步都应该是SORT JOIN,但这里表TEST1却是TABLE
ACCESS BY INDEX ROWID TEST1,我想原因应该是:

(a) 对TEST2表的扫描使用的是INDEX FULL SCAN SYS_C0016790,即使用的索引快速全扫描,扫描t1id的主键索引数据块

(b) 索引都是有序的,因此INDEX FULL SCAN SYS_C0016790的结果也是相当于排序的

(c) 既然之前已经是排序的结果,那么按照有序索引对应的ROWID,找到对应的记录也是有序的,TABLE ACCESS BY INDEX ROWID TEST1,所以不用显示SORT
JOIN再次排序了

时间: 2024-10-14 01:42:28

经典10046剖析案例-1的相关文章

经典10046剖析案例-3

执行计划+Hint+统计信息+并行+绑定变量+sql跟踪和10046事件+10053事件总结 执行计划 1.执行计划中的rows表示CBO从一个行源预期获取的记录数,这个行源可能是一个表,也可能是一个索引. 2.rows值对CBO做出正确的执行计划至关重要,如果CBO获取的rows值不准确(通常是没收集统计信息或统计信息过旧导致),在计算执行成本时就会出现偏差,从而制定出错误的执行计划. 3.收集统计信息 exec dbms_stats.gather_table_stats('username'

经典10046剖析案例-4

sql_trace和10046事件都是我们在优化sql上面应用的非常多的工具,我们可以使用这两个工具知道当前正在执行的sql究竟在做什么 一,SQL_TRACE: SQL_TRACE命令会将执行的整个过程输出到一个trace文件,我通过阅读这个trace文件来了解这个sql在执行过程中Oracle究竟做了哪些事情 1)确定trace文件的路径 启用sql_trace前我们首先要确定跟踪文件的存放位置,即user_dump_dest下 SQL> show parameter user_dump_d

经典10046剖析案例-2

10046 trace的跟踪等级 10046是一个Oracle的内部事件(event),通过设置这个事件可以得到Oracle内部执行系统解析.调用.等待.绑定变量等详细的trace信息,对于分析系统的性能有着非常重要的作用. 设置10046事件的不同级别能得到不同详细程度的trace信息,下面就列出各个不同级别的对应作用: 等级 二进制 作用 0 0000 无输出 1 0001 输出 ****,APPNAME(应用程序名),PARSING IN CURSOR,PARSE ERROR(SQL解析)

经典10046剖析案例-5

The header /appl/oracle/admin/EI1T/udump/ei1t_ora_14246.trc Oracle9i Enterprise Edition Release 9.2.0.3.0 - 64bit Production JServer Release 9.2.0.3.0 - Production ORACLE_HOME = /appl/oracle/product/9.2.0 System name:    SunOS Node name:      sdsunn0

[转载]HTML5开发入门经典教程和案例合集(含视频教程)

http://www.iteye.com/topic/1132555 HTML5作为下一代网页语言,对Web开发者而言,是一门必修课.本文档收集了多个HTML5经典技术文档(HTML5入门资料.经典)以及游戏开发案例以及教学视频等,帮助同学们掌握这门重要的技术. 资源名称                                资源地址 WEB新技术:HTML5介绍 http://down.51cto.com/data/385440 HTML5跨平台游戏开发 http://down.51c

十分钟完成Bash 脚本进阶!列举Bash经典用法及其案例

前言:在linux中,Bash脚本是很基础的知识,大家可能一听脚本感觉很高大上,像小编当初刚开始学一样,感觉会写脚本的都是大神.虽然复杂的脚本是很烧脑,但是,当我们熟练的掌握了其中的用法与技巧,再多加练习,总有一天也会成为得心应手的脚本大神.脚本在生产中的作用,想必小编我不说,大家也都知道,脚本写的6,可以省下很多复杂的操作,减轻自己的工作压力.好了,废话不多说,接下来,就是Bash脚本的用法展示. 一.条件选择.判断(if·.case) 二.四个循环(for.while.until.selec

步步为营-03-一个经典的多态案例

说明:相信大家都知道一个经典的案例.关于电脑对不同的设备进行读取. 1 定义一个基类(移动存储设备类)其中包括两个虚方法 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Computer { public abstract class MobileDevice { public abstract

Bash 脚本进阶,经典用法及其案例

前言:在linux中,Bash脚本是很基础的知识,大家可能一听脚本感觉很高大上,像小编当初刚开始学一样,感觉会写脚本的都是大神.虽然复杂的脚本是很烧脑,但是,当我们熟练的掌握了其中的用法与技巧,再多加练习,总有一天也会成为得心应手的脚本大神.脚本在生产中的作用,想必小编我不说,大家也都知道,脚本写的6,可以省下很多复杂的操作,减轻自己的工作压力.好了,废话不多说,接下来,就是Bash脚本的用法展示. 一.条件选择.判断(if·.case) 二.四个循环(for.while.until.selec

sql语句复习(基础-提升-技巧-经典数据开发案例-sql server配置)

1 基础 1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份sql server --- 创建 备份数据的 deviceUSE masterEXEC sp_addumpdevice 'disk', 'testBack', 'c:mssql7backupMyNwind_1.dat'--- 开始 备份BACKUP DATABASE pubs TO testBack 4.说明:创建新表 cre