查看Oracle执行计划的几种常用方法-系列3

续上篇:http://blog.csdn.net/bisal/article/details/39225373

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再次排序了

未完待续。。。

​To Be Continued ...

时间: 2024-11-09 00:30:04

查看Oracle执行计划的几种常用方法-系列3的相关文章

查看Oracle执行计划的几种常用方法-系列1

SQL的执行计划实际代表了目标SQL在Oracle数据库内部的具体执行步骤,作为调优,只有知道了优化器选择的执行计划是否为当前情形下最优的执行计划,才能够知道下一步往什么方向. 执行计划的定义:执行目标SQL的所有步骤的组合. 我们首先列出查看执行计划的一些常用方法: 1. explain plan命令 PL/SQL Developer中通过快捷键F5就可以查看目标SQL的执行计划了.但其实按下F5后,实际后台调用的就是explain plan命令,相当于封装了该命令. explain plan

查看Oracle执行计划的几种常用方法-系列2

续上篇:http://blog.csdn.net/bisal/article/details/38919181 3. AUTOTRACE开关 SQLPLUS中打开AUTOTRACE开关可以得到SQL的执行计划. 从提示可以看到AUTOTRACE有几个选项: OFF/ON/TRACEONLY/EXPLAIN/STATISTICS. 实验: 1. 执行SET AUTOTRACE ON: 2. 执行SET AUTOTRACE TRACEONLY: 3. 执行SET AUTOTRACE TRACEONL

查看oracle执行计划方法( 一)

关于oracle执行计划的概念,参考之前的博客:http://blog.csdn.net/cymm_liu/article/details/7996599 如果要分析某条SQL的性能问题,通常我们要先看SQL的执行计划,看看SQL的每一步执行是否存在问题. 如果一条SQL平时执行的好好的,却有一天突然性能很差,如果排除了系统资源和阻塞的原因,那么基本可以断定是执行计划出了问题. 看懂执行计划也就成了SQL优化的先决条件. 这里的SQL优化指的是SQL性能问题的定位,定位后就可以解决问题. 一. 

查看oracle执行计划方法( 二)

1.Cardinality(基数)/ rows Cardinality值表示CBO预期从一个行源(row source)返回的记录数,这个行源可能是一个表,一个索引,也可能是一个子查询.   在Oracle 9i中的执行计划中,Cardinality缩写成Card. 在10g中,Card值被rows替换.   这是9i的一个执行计划,我们可以看到关键字Card:        执行计划 -------------------------------------------------------

如何查看Oracle执行计划

1)最简单的方法是,用PL/SQL 工具登录进去后,选中sql语句,然后按F5: 2)用PL/SQL工具登录进去后,打开command窗口 a) 执行:explain plan for select * from dual;--红色部分可替换为你的sql语句 b) 执行:select * from table(dbms_xplan.display()),即可获得执行计划; 3)用sqlplus命令登录,执行set autotrace traceonly;即可获得执行计划: 本栏目更多精彩内容:h

Oracle查看执行计划的几种方法

Oracle查看执行计划的几种方法   一般来说,有如下几种获取执行计划的方式: 1.AUTOTRACE方式 AUTOTRACE是Oracle自带的客户端工具SQL*Plus的一个特性.启用AUTOTRACE后,SQL*Plus会自动收集执行过的SQL语句的执行计划.性能统计数据等,并在语句执行结束后显示在SQL*Plus中. DBA用户可以直接使用AUTOTRACE功能,但是如果用户没有DBA权限,那么需要在SYS用户下执行plustrce.sql脚本,自动创建PLUSTRACE角色,再把PL

Oracle中获取执行计划的几种方法

1. 预估执行计划 - Explain Plan Explain plan以SQL语句作为输入,得到这条 SQL语句的执行计划,并将执行计划输出存储到计划表中. 首先,在你要执行的SQL语 句前加explain plan for,此时将生成的执行计划存储到计划表中,语句如下: explain plan for SQL语句 然后,在计划表中查询刚刚生成的执行计划,语 句如下: select * from table(dbms_xplan.display); 注意:Explain plan 只生成执

Oracle中获取执行计划的几种方法分析

以下是对Oracle中获取执行计划的几种方法进行了详细的分析介绍,需要的朋友可以参考下   1. 预估执行计划 - Explain PlanExplain plan以SQL语句作为输入,得到这条SQL语句的执行计划,并将执行计划输出存储到计划表中. 首先,在你要执行的SQL语句前加explain plan for,此时将生成的执行计划存储到计划表中,语句如下: explain plan for SQL语句然后,在计划表中查询刚刚生成的执行计划,语句如下: select * from table(

Oracle中获取执行计划的几种方法分析_oracle

1. 预估执行计划 - Explain PlanExplain plan以SQL语句作为输入,得到这条SQL语句的执行计划,并将执行计划输出存储到计划表中. 首先,在你要执行的SQL语句前加explain plan for,此时将生成的执行计划存储到计划表中,语句如下:explain plan for SQL语句然后,在计划表中查询刚刚生成的执行计划,语句如下:select * from table(dbms_xplan.display);注意:Explain plan只生成执行计划,并不会真正