[20120915]10046事件与执行计划改变.txt


    使用10046事件来跟踪解决oracle的许多问题,是非常常用的手段,但是实际上可能出现跟踪的sql执行计划与原来不同的情况,自己应该引起注意.
测试如下:
1.测试环境建立:
SQL> select * from v$version ;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

SQL> create table t as select rownum id , 'test' name from dual connect by level
Table created.
SQL> insert into t select 1e4+1 ,'book' from dual connect by level
10000 rows created.
SQL> create index i_t_id on t(id);
Index created.
--可以发现id分布不均匀,而且10001占了50%.建立直方图看看.
SQL> exec dbms_stats.gather_table_stats(ownname=>user,tabname=>'T',cascade=>true,method_opt=>'for all columns size 254');
PL/SQL procedure successfully completed.
2.开始测试:
SQL> variable v_id number ;
SQL> exec :v_id := 42;
PL/SQL procedure successfully completed.
SQL> select * from t where id=:v_id;
        ID NAME
---------- ----
        42 test
SQL> @dpc ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  d9msgvzah6u4p, child number 0
-------------------------------------
select * from t where id=:v_id
Plan hash value: 4153437776
--------------------------------------------------------------------
| Id  | Operation                   | Name   | E-Rows | Cost (%CPU)|
--------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |        |     2 (100)|
|   1 |  TABLE ACCESS BY INDEX ROWID| T      |      1 |     2   (0)|
|*  2 |   INDEX RANGE SCAN          | I_T_ID |      1 |     1   (0)|
--------------------------------------------------------------------
Peeked Binds (identified by position):
--------------------------------------
   1 - (NUMBER): 42
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("ID"=:V_ID)
Note
-----
   - Warning: basic plan statistics not available. These are only collected when:
       * hint 'gather_plan_statistics' is used for the statement or
       * parameter 'statistics_level' is set to 'ALL', at session or system level
30 rows selected.
将select * from t where id=:v_id;执行多次,避免ACS的影响.(我使用的是11G).

SQL> select sql_text,sql_id,child_number,executions from v$sql where sql_id='d9msgvzah6u4p';
SQL_TEXT                                 SQL_ID        CHILD_NUMBER EXECUTIONS
---------------------------------------- ------------- ------------ ----------
select * from t where id=:v_id           d9msgvzah6u4p            0          9

3.打开10046跟踪看看:
SQL> exec :v_id := 10001;
PL/SQL procedure successfully completed.
SQL> alter session set events '10046 trace name context forever, level 12';
Session altered.
SQL> select * from t where id=:v_id;
...
SQL> alter session set events '10046 trace name context off';
SQL> select sql_text,sql_id,child_number,executions from v$sql where sql_id='d9msgvzah6u4p';
SQL_TEXT                                 SQL_ID        CHILD_NUMBER EXECUTIONS
---------------------------------------- ------------- ------------ ----------
select * from t where id=:v_id           d9msgvzah6u4p            0          9
select * from t where id=:v_id           d9msgvzah6u4p            1          1
--查看视图V$SQL,发现生成了新的子光标.
SQL> select * from table(dbms_xplan.display_cursor('d9msgvzah6u4p',1,'ALLSTATS LAST PEEKED_BINDS cost'));
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------
SQL_ID  d9msgvzah6u4p, child number 1
-------------------------------------
select * from t where id=:v_id
Plan hash value: 1601196873
-------------------------------------------------------------------------------------------------
| Id  | Operation         | Name | Starts | E-Rows | Cost (%CPU)| A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |      1 |        |    14 (100)|  10000 |00:00:00.01 |      96 |
|*  1 |  TABLE ACCESS FULL| T    |      1 |  10039 |    14   (0)|  10000 |00:00:00.01 |      96 |
-------------------------------------------------------------------------------------------------
Peeked Binds (identified by position):
--------------------------------------
   1 - (NUMBER): 10001
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("ID"=:V_ID)
23 rows selected.
--查看跟踪文件也可以发现,执行计划发生了变化:
SQL ID: d9msgvzah6u4p
Plan Hash: 1601196873
select *
from
 t where id=:v_id

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       51      0.00       0.00          0         96          0       10000
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total       53      0.00       0.01          0         96          0       10000
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 84
Rows     Row Source Operation
-------  ---------------------------------------------------
  10000  TABLE ACCESS FULL T (cr=96 pr=0 pw=0 time=11152 us cost=14 size=90351 card=10039)

4.看看什么导致的光标不能共享:
SQL> @share d9msgvzah6u4p
SQL_TEXT                       = select * from t where id=:v_id
SQL_ID                         = d9msgvzah6u4p
ADDRESS                        = 00000000DE2DC258
CHILD_ADDRESS                  = 00000000DE2DBE58
CHILD_NUMBER                   = 0
--------------------------------------------------
SQL_TEXT                       = select * from t where id=:v_id
SQL_ID                         = d9msgvzah6u4p
ADDRESS                        = 00000000DE2DC258
CHILD_ADDRESS                  = 00000000DE29D1B8
CHILD_NUMBER                   = 1
STATS_ROW_MISMATCH             = Y
--------------------------------------------------
PL/SQL procedure successfully completed.
--可以发现实际上STATS_ROW_MISMATCH=Y.
    也就是将在开启跟踪后,会话执行的SQL将不会重用以前的的执行计划,发生硬解析。由于硬解析时要发生绑定变量窥视,将会使硬解析产生的子游标,而这里由于
ID数据的分布变化,导致其执行计划可能发生了变化。
5.实际上这种情况很多:
比如设置optimizer_capture_sql_plan_baselines=true也会出现类似情况.
设置sql_trace =true等.
时间: 2024-11-13 04:21:28

[20120915]10046事件与执行计划改变.txt的相关文章

[20120214]异常数据导致执行计划改变.txt

今天上午,用户反应一条sql执行有点慢.我检查发现,原来使用索引的语句现在变成了全表扫描,而且昨晚oracle数据库自动分析过这个表. 语句很复杂,抽取有问题的部分: SELECT *  FROM med_operation_schedule a WHERE (       scheduled_date_time >= TO_DATE ('2012-02-15 00:00', 'yyyy-mm-dd hh24:mi')           AND scheduled_date_time     

oracle 执行计划改变导致数据库负载过高解决办法

数据库主机负载 这里明显表现系统load 偏高,而且还在上升中:top的进程中,占用cpu都计划100% top - 16:25:39 up 123 days,  1:42,  4 users,  load average: 46.19, 45.08, 43.93 Tasks: 1469 total,  28 running, 1439 sleeping,   0 stopped,   2 zombie Cpu(s): 45.9%us,  1.1%sy,  0.0%ni, 47.1%id,  5

[20131121]奇怪的执行计划变化.txt

[20131121]奇怪的执行计划变化.txt SCOTT@test> @verBANNER--------------------------------------------------------------------------------Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production create table t pctfree 99 as select rownum id,l

oracle11g中 connect by 语句执行计划改变

从10.2.0.3升级到11.2.0.4的朋友,如果细心会发现,以下sql在11.2.0.4中执行效率变低(该sql主要是获取连接用户获取权限信息) select privilege#,level from sysauth$ connect by grantee#=prior privilege# and privilege#>0 start with grantee#=:1 and privilege#>0 如果你接触是Oracle版本比较多,而且还比较细心,你可能会进一步发现在11.2.0

[20121212]谨慎使用set autotrace traceonly查看执行计划[补充].txt

使用toad自带sqlmonitor,toad10以上版本现在叫sqltrace. 12:00:24 SQL> set autotrace traceonly ;12:01:23 SQL> select * from t2 where id=45; 10000 rows selected. Execution Plan----------------------------------------------------------Plan hash value: 1513984157 ---

[20140109]显示执行计划的问题.txt

昨天看别人调优,我跟对方讲使用SET Autotrace看执行计划可能不真实的. 自己做一个简单的例子来说明: 1.建立测试环境: SCOTT@test> @ver BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production cr

一个执行计划异常变更的案例 - 外传之查询执行计划的几种方法

之前的几篇文章: <一个执行计划异常变更的案例 - 前传> <一个执行计划异常变更的案例 - 外传之绑定变量窥探> <一个执行计划异常变更的案例 - 外传之查看绑定变量值的几种方法> <一个执行计划异常变更的案例 - 外传之rolling invalidation> <一个执行计划异常变更的案例 - 外传之聚簇因子(Clustering Factor)> 本篇外传主要介绍一些常用的执行计划查看方法. SQL的执行计划实际代表了目标SQL在Orac

查看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中直方图是一种对数据分布质量情况进行描述的工具.它会按照某一列不同值出现数量多少,以及出现的频率高低来绘制数据的分布情况,以便能够指导优化器根据数据的分布做出正确的选择.在某些情况下,表的列中的数值分布将会影响优化器使用索引还是执行全表扫描的决策.当 where 子句的值具有不成比例数量的数值时,将出现这种情况,使得全表扫描比索引访问的成本更低.这种情况下如果where 子句的过滤谓词列之上上有一个合理的正确的直方图,将会对优化器做出正确的选择发挥巨大的作用,使得SQL语句执行成本