关闭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 ...