10046 raw trace file does not have the same execution plan as autotrace and expl_MySQL, Oracle及数据库讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MySQL, Oracle及数据库讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 2146 | 回复: 0   主题: 10046 raw trace file does not have the same execution plan as autotrace and expl        下一篇 
大红薯
注册用户
等级:少校
经验:1440
发帖:159
精华:0
注册:2011-7-21
状态:离线
发送短消息息给大红薯 加好友    发送短消息息给大红薯 发消息
发表于: IP:您无权察看 2015-4-10 11:31:07 | [全部帖] [楼主帖] 楼主

我们查看sql语句的执行计划有set autotrace,explain plan for和10046 raw trace三种主要方式,但在有绑定变量存在的情况时,默认情况下10046 raw trace得到的执行计划与另外两种主要方式不同。以下给出了一个演示:

1、初始化环境数据并收集统计信息

 SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE 11.2.0.3.0 Production
TNS for Linux: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production
SQL> conn syk/syk
Connected.
SQL> DROP TABLE T_BIND_VAR PURGE;
Table dropped.
SQL> CREATE TABLE T_BIND_VAR ( A INT, B VARCHAR(64));
Table created.
SQL> create index inx_a on T_BIND_VAR(A);
Index created.
SQL> begin
2 for i in 1..10000 loop
3 insert into t_bind_var values (1,DBMS_RANDOM.STRING('B',64));
4 end loop;
5 end;
6 /
PL/SQL procedure successfully completed.
SQL> update t_bind_var set a = 2 where rownum <=1;
1 rows updated.
SQL> commit;
Commit complete.
SQL> begin
2 dbms_stats.gather_table_stats(
3 ownname => 'SYK',
4 tabname => 'T_BIND_VAR',
5 estimate_percent => null,
6 method_opt => 'for all indexed columns',
7 cascade => true);
8 end;
9 /
PL/SQL procedure successfully completed.
SQL> select endpoint_value,
2 endpoint_number,
3 endpoint_number - lag(endpoint_number, 1, 0) over(order by endpoint_number) as frequency
4 from user_tab_histOgrams
5 where table_name = 'T_BIND_VAR'
6 AND COLUMN_NAME = 'A'
7 ORDER BY ENDPOINT_NUMBER;
ENDPOINT_VALUE ENDPOINT_NUMBER FREQUENCY
-------------- --------------- ----------
1 9999 9999
2 10000 1


2、对比执行计划

脚本xplan_with_bind.sql中包含了三种获取执行计划的方式,执行脚本可以获得三种方式所产生的结果。

SQL> ! cat xplan_with_bind.sql
set linesize 80 pagesize 200 echo on feedback off
var v_a number
exec :v_a := 2
explain plan for SELECT * FROM T_BIND_VAR WHERE A = :v_a;
select * from table(dbms_xplan.display);
SET AUTOT ON EXPLAIN
SELECT * FROM T_BIND_VAR WHERE A = :v_a;
SET AUTOT OFF
alter session set events='10046 trace name context forever,level 12';
SELECT * FROM T_BIND_VAR WHERE A = :v_a;
alter session set events='10046 trace name context off';
SELECT VALUE FROM V$DIAG_INFO WHERE NAME = 'Default Trace File';
exit
SQL> conn syk/syk
Connected.
SQL> @xplan_with_bind
SQL> var v_a number
SQL> exec :v_a := 2
SQL> explain plan for SELECT * FROM T_BIND_VAR WHERE A = :v_a;
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 3172564556
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5000 | 180K| 30 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T_BIND_VAR | 5000 | 180K| 30 (0)| 00:00:01 |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("A"=TO_NUMBER(:V_A))
SQL> SET AUTOT ON EXPLAIN
SQL> SELECT * FROM T_BIND_VAR WHERE A = :v_a;
A B
---------- ----------------------------------------------------------------
2 TUABBMPSWVDCUUBXGNSVQZEEOPLNDZJFAZIJSROBEUJMIJIVRDSTIGGHJMOFLYYX
Execution Plan
----------------------------------------------------------
Plan hash value: 3172564556
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5000 | 180K| 30 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T_BIND_VAR | 5000 | 180K| 30 (0)| 00:00:01 |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("A"=TO_NUMBER(:V_A))
SQL> SET AUTOT OFF
SQL> alter session set events='10046 trace name context forever,level 12';
SQL> SELECT * FROM T_BIND_VAR WHERE A = :v_a;
A B
---------- ----------------------------------------------------------------
2 TUABBMPSWVDCUUBXGNSVQZEEOPLNDZJFAZIJSROBEUJMIJIVRDSTIGGHJMOFLYYX
SQL> alter session set events='10046 trace name context off';
SQL> SELECT VALUE FROM V$DIAG_INFO WHERE NAME = 'Default Trace File';
VALUE
--------------------------------------------------------------------------------
/oracle/diag/rdbms/aceace/ACE/trace/ACE_ora_27886.trc


检查上述raw trace文件,可以发现下面的片段,其中包含了执行计划:

=====================
PARSING IN CURSOR #47474678551288 len=39 dep=0 uid=91 oct=3 lid=91 tim=1349864661566215 hv=3864287956 ad='ae6d3cf8' sqlid='91t6tngm58qqn'
SELECT * FROM T_BIND_VAR WHERE A = :v_a
END OF STMT
PARSE #47474678551288:c=1000,e=499,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=2359727817,tim=1349864661566208
BINDS #47474678551288:
Bind#0
oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
oacflg=03 fl2=1000000 frm=00 csi=00 siz=24 off=0
kxsbbbfp=2b2d8f5cf300 bln=22 avl=02 flg=05
value=2
EXEC #47474678551288:c=1000,e=798,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=2359727817,tim=1349864661567125
WAIT #47474678551288: nam='SQL*Net message to client' ela= 1 driver id=1650815232 #bytes=1 p3=0 obj#=-1 tim=1349864661567237
FETCH #47474678551288:c=0,e=117,p=0,cr=3,cu=0,mis=0,r=1,dep=0,og=1,plh=2359727817,tim=1349864661567385
WAIT #47474678551288: nam='SQL*Net message from client' ela= 191 driver id=1650815232 #bytes=1 p3=0 obj#=-1 tim=1349864661567621
FETCH #47474678551288:c=0,e=4,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=2359727817,tim=1349864661567650
STAT #47474678551288 id=1 cnt=1 pid=0 pos=1 obj=82005 op='TABLE ACCESS BY INDEX ROWID T_BIND_VAR (cr=3 pr=0 pw=0 time=175 us cost=2 size=37 card=1)'
STAT #47474678551288 id=2 cnt=1 pid=1 pos=1 obj=82006 op='INDEX RANGE SCAN INX_A (cr=2 pr=0 pw=0 time=128 us cost=1 size=0 card=1)'
WAIT #47474678551288: nam='SQL*Net message to client' ela= 1 driver id=1650815232 #bytes=1 p3=0 obj#=-1 tim=1349864661568391
WAIT #47474678551288: nam='SQL*Net message from client' ela= 748 driver id=1650815232 #bytes=1 p3=0 obj#=-1 tim=1349864661569212
CLOSE #47474678551288:c=0,e=6,dep=0,type=0,tim=1349864661569246
=====================


使用tkprof工具格式化后的trace文件可以发现下面的片段:

SQL ID: 91t6tngm58qqn Plan Hash: 2359727817
SELECT *
FROM
T_BIND_VAR WHERE A = :v_a
call   count   cpu   elapsed   disk  query  current  rows
------ ------ -------- -------- ------- -------- -------- ---------
Parse    1   0.00   0.00     0     0     0      0
Execute   1   0.00   0.00     0     0     0      0
Fetch    2   0.00   0.00     0     3     0      1
------ ------ -------- -------- ------- -------- -------- ----------
total    4   0.00   0.00     0     3     0      1
Misses in library cache during parse: 0
Optimizer mode: ALL_ROWS
Parsing user id: 91
Number of plan statistics captured: 1
Rows (1st) Rows (avg) Rows (max) Row Source Operation
---------- ---------- ---------- ---------------------------------------------------
1       1        1  TABLE ACCESS BY INDEX ROWID T_BIND_VAR (cr=3 pr=0 pw=0 time=175 us cost=2 size=37 card=1)
1       1        1  INDEX RANGE SCAN INX_A (cr=2 pr=0 pw=0 time=128 us cost=1 size=0 card=1)(object id 82006)


可以看出三种方式得出的结果并不是完全一样。

3、原因

MOS给的原因解释是

1.Bind Peeking (9.2 and later):

A real execution peeks bind values during the hard parse. “Explain Plan” and SQL*PLUS AUTOTRACE do NOT peek bind values when they generate plans.
2.Data Type Conversion:
For example, the type of a character column is converted when it is compared with a numeric value. In this case, the index on the column cannot be used. But, “Explain Plan” and SQL*PLUS AUTOTRACE do NOT consider data type conversion.


4、解决方案

使用SQL TRACE(10046 trace)方式获取正确的执行计划。另外,如果知晓sql_id,亦可以使用V$SQL_PLAN或DBMS_XPLAN.DISPLAY_CURSOR获得正确的执行计划。

--转自 北京联动北方科技有限公司




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论