[20120327]Adaptive Cursor Sharing 的问题

[20120327]Adaptive Cursor SharingG 的问题

11G的新特性里面Adaptive Cursor Sharing采用新特性来解决PEEKED BIND的问题,但是必须要经过一次执行后,来改变执行计划。
但是如果在一些工具里面,它执行并不是提取全部的信息,而是取一部分就会遭遇执行计划不改变的问题。

如下站点:
http://jonathanlewis.wordpress.com/2012/03/21/acs/
按照讲解是一个BUG,但是没有给出例子,自己写个例子测试如下:

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 t1 as select rownum id,'test' name from dual connect by level
Table created.
SQL> insert into t1 select 1001 id,'book' name  from dual connect by level
1000 rows created.
SQL> commit;
Commit complete.
SQL> create index i_t1_id on t1(id);
Index created.
SQL>exec SYS.DBMS_STATS.GATHER_TABLE_STATS (user,'T1',Method_Opt => 'FOR ALL COLUMNS SIZE 254 ');
SQL> column data_type format a20
SQL> select table_name,column_name,data_type,histogram from dba_tab_cols where wner='SCOTT' and table_name='T1';
TABLE_NAME                     COLUMN_NAME                    DATA_TYPE            HISTOGRAM
------------------------------ ------------------------------ -------------------- ---------------
T1                             ID                             NUMBER               HEIGHT BALANCED
T1                             NAME                           CHAR                 FREQUENCY
SQL> alter system flush shared_pool;

2.执行sql语句,为了更好测试,我在toad执行,:a :=1 :

select /*+ testme */ * from t1 where id = :a;
        ID NAME
---------- ----
         1 test
column is_bind_sensitive format a20
column is_bind_aware     format a20
column is_shareable      format a20
SELECT sql_id, sql_text, child_number, plan_hash_value, executions, is_bind_sensitive, is_bind_aware, is_shareable
FROM v$sql
WHERE sql_text LIKE '%testme%' AND sql_text NOT LIKE '%sql_text%'
SQL_ID        SQL_TEXT                       CHILD_NUMBER PLAN_HASH_VALUE EXECUTIONS IS_BIND_SENSITIVE    IS_BIND_AWARE        IS_SHAREABLE
------------- ------------------------------ ------------ --------------- ---------- -------------------- -------------------- --------------------
9rx9cq6x20guk select /*+ testme */ * from t1            0      1111474805          1 Y                    N                    Y
               where id = :a

--知道sql_id=9rx9cq6x20guk.
SQL> select * from table(dbms_xplan.display_cursor('9rx9cq6x20guk',NULL,'allstats last peeked_binds'));
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  9rx9cq6x20guk, child number 0
-------------------------------------
select /*+ testme */ * from t1 where id = :a
Plan hash value: 1111474805
--------------------------------------------------------
| Id  | Operation                   | Name    | E-Rows |
--------------------------------------------------------
|   0 | SELECT STATEMENT            |         |        |
|   1 |  TABLE ACCESS BY INDEX ROWID| T1      |      1 |
|*  2 |   INDEX RANGE SCAN          | I_T1_ID |      1 |
--------------------------------------------------------
Peeked Binds (identified by position):
--------------------------------------
   1 - (NUMBER): 1
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("ID"=:A)
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.

3.在toad下执行相同的sql语句,但是带入的参数是1001:

SQL_ID        SQL_TEXT                       CHILD_NUMBER PLAN_HASH_VALUE EXECUTIONS IS_BIND_SENSITIVE    IS_BIND_AWARE        IS_SHAREABLE
------------- ------------------------------ ------------ --------------- ---------- -------------------- -------------------- --------------------
9rx9cq6x20guk select /*+ testme */ * from t1            0      1111474805          2 Y                    N                    Y
               where id = :a

--执行多次,参数1001,可以发现执行计划并没有产生子光标。

再次执行在toad下执行相同的sql语句,但是带入的参数是1001:

SQL_ID        SQL_TEXT                       CHILD_NUMBER PLAN_HASH_VALUE EXECUTIONS IS_BIND_SENSITIVE    IS_BIND_AWARE        IS_SHAREABLE
------------- ------------------------------ ------------ --------------- ---------- -------------------- -------------------- --------------------
9rx9cq6x20guk select /*+ testme */ * from t1            0      1111474805          4 Y                    N                    Y
               where id = :a

--可以发现并没有产生新的子光标.换句话讲Adaptive Cursor Sharing并没有起作用。

现在toad打开auto trace(具体操作是在sql编辑器里面,点击右键选择auto trace),主要目的是这样可以提取全部查询信息。
再次执行以上语句。参数1001

SQL_ID        SQL_TEXT                       CHILD_NUMBER PLAN_HASH_VALUE EXECUTIONS IS_BIND_SENSITIVE    IS_BIND_AWARE        IS_SHAREABLE
------------- ------------------------------ ------------ --------------- ---------- -------------------- -------------------- --------------------
9rx9cq6x20guk select /*+ testme */ * from t1            0      1111474805          5 Y                    N                    Y
               where id = :a

再次执行以上语句。参数1001

SQL_ID        SQL_TEXT                       CHILD_NUMBER PLAN_HASH_VALUE EXECUTIONS IS_BIND_SENSITIVE    IS_BIND_AWARE        IS_SHAREABLE
------------- ------------------------------ ------------ --------------- ---------- -------------------- -------------------- --------------------
9rx9cq6x20guk select /*+ testme */ * from t1            0      1111474805          5 Y                    N                    Y
               where id = :a
9rx9cq6x20guk select /*+ testme */ * from t1            1      3617692013          1 Y                    Y                    Y
               where id = :a

--可以发现现在出现了新的子光标。

SQL> select * from table(dbms_xplan.display_cursor('9rx9cq6x20guk',NULL,'allstats last peeked_binds'));
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  9rx9cq6x20guk, child number 0
-------------------------------------
select /*+ testme */ * from t1 where id = :a
Plan hash value: 1111474805
--------------------------------------------------------
| Id  | Operation                   | Name    | E-Rows |
--------------------------------------------------------
|   0 | SELECT STATEMENT            |         |        |
|   1 |  TABLE ACCESS BY INDEX ROWID| T1      |      1 |
|*  2 |   INDEX RANGE SCAN          | I_T1_ID |      1 |
--------------------------------------------------------
Peeked Binds (identified by position):
--------------------------------------
   1 - (NUMBER): 1
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("ID"=:A)
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
SQL_ID  9rx9cq6x20guk, child number 1
-------------------------------------
select /*+ testme */ * from t1 where id = :a
Plan hash value: 3617692013
-------------------------------------------
| Id  | Operation         | Name | E-Rows |
-------------------------------------------
|   0 | SELECT STATEMENT  |      |        |
|*  1 |  TABLE ACCESS FULL| T1   |   1012 |
-------------------------------------------
Peeked Binds (identified by position):
--------------------------------------
   1 - (NUMBER): 1001
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("ID"=:A)
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
59 rows selected.
4.再次执行以上语句。参数1

SELECT sql_id, sql_text, child_number, plan_hash_value, executions, is_bind_sensitive, is_bind_aware, is_shareable
FROM v$sql
WHERE sql_text LIKE '%testme%' AND sql_text NOT LIKE '%sql_text%';
SQL_ID        SQL_TEXT                       CHILD_NUMBER PLAN_HASH_VALUE EXECUTIONS IS_BIND_SENSITIVE    IS_BIND_AWARE        IS_SHAREABLE
------------- ------------------------------ ------------ --------------- ---------- -------------------- -------------------- --------------------
9rx9cq6x20guk select /*+ testme */ * from t1            0      1111474805          5 Y                    N                    N
               where id = :a
9rx9cq6x20guk select /*+ testme */ * from t1            1      3617692013          1 Y                    Y                    Y
               where id = :a
9rx9cq6x20guk select /*+ testme */ * from t1            2      1111474805          1 Y                    Y                    Y
               where id = :a

--可以发现child_number=0 的子光标IS_SHAREABLE='N'.

5.如果要避免这样的问题,最好的方法是使用提示/*+ bind_aware */.

时间: 2024-09-20 23:22:39

[20120327]Adaptive Cursor Sharing 的问题的相关文章

[20120220]Adaptive Cursor Sharing 与hints.txt

11G的新特性里面Adaptive Cursor Sharing采用新特性来解决PEEKED BIND的问题,但是必须要经过一次执行后,来改变执行计划.能否绕过这个步骤,选择合理的执行计划呢?从11G开始也提供一个提示BIND_AWARE来绕过这个特性,直接选择合理的执行计划. 例子如下: 1.环境说明:SQL> select * from v$version ; BANNER------------------------------------------------------------

Oracle游标共享(Cursor Sharing)--常规游标共享和自适应游标共享(ACS)

Oracle游标共享(Cursor Sharing)--常规游标共享和自适应游标共享(ACS) 游标共享(Cursor Sharing)是指Shared Cursor间的共享,其实就是重用存储在Child Cursor中的解析树和执行计划而不用从头开始做硬解析的动作.特别对于除SQL文本中对应的输入值不同外,其它部分都一模一样的目标SQL更应该实现游标共享,而使用绑定变量就可以实现游标共享. 很多OLTP类型的应用系统的开发人员在开发阶段并未意识到硬解析的危害,所以也没有使用绑定变量,等到系统上

Oracle: 变量绑定

Parent-Child cursor (父子游标) 父游标:只要SQL语句文本相同,它们就对应 同一个parent cursor. 子游标:在某些情况下,虽然SQL语句的文本相同,但是因为其它 因素不同(这些因素可以在视图V$SQL_SHARED_CURSOR中查看),导致产生不同的child cursor.(重新生成child cursor,也就意味着一次硬解析) cursor_sharing 对 于是否使用绑定变量这个问题,最好是交给应用程序决定,在数据库层面是很难正确判断. (这也是为什

The Query Optimizer

The Query Optimizer This chapter discusses SQL processing, optimization methods, and how the query optimizer (usually called the optimizer) chooses a specific plan to execute SQL. The chapter contains the following sections: Overview of the Query Opt

cursor_sharing设置为similar 的弊端

将cursor_sharing设置为similar会产生许多问题:1.对于语句中包含的范围查询(如between, <, !=)或者所捆绑的列中进行直方图统计不适合使用:2.影响11g Adaptive Cursor sharing特性和CBO优化器3.Similar可能产生的一个父游标, 多个子游标,其性能比多个父游标情况更加糟糕(EXACT或 FORCE); 对于第一个,我们做实验如下: 1 修改参数,建表,统计信息 yang@rac1>alter session set cursor_s

【重磅干货】看了此文,Oracle SQL优化文章不必再看!

听"俊"一席话,胜读十年书.看了这篇由DBA+社群联合发起人丁俊大师(网名:dingjun123)分享的SQL优化大作,其他Oracle SQL优化文章都不必再看了!   专家简介    丁俊 网名:dingjun123 DBA+社群联合发起人   性能优化专家,Oracle ACEA,ITPUB开发版资深版主.8年电信行业从业经验,在某大型电信系统提供商工作7年,任资深工程师,从事过系统开发与维护.业务架构和数据分析.系统优化等工作.擅长基于ORACLE的系统优化,精通SQL.PL/

Oracle原厂老兵:从负面案例看Hint的最佳使用方式

作者介绍 罗敏,从事Oracle技术研究.开发和服务工作20余年,在Oracle中国公司的10多年,分别在顾问咨询部.技术服务部担任资深技术顾问.曾参与国内银行.电信.政府等多个行业大型IT系统的建设和运维服务工作,为国内主要软件开发商和集成商进行过多场Oracle高级技术应用培训和交流活动.著有书籍<品悟性能优化>.<感悟Oracle核心技术>.<Oracle数据库技术服务案例精选>.   Oracle真灵活     某银行广泛采用了Oracle和IBM DB2两种数

[转载】&amp;mdash;&amp;mdash;故障排除:Shared Pool优化和Library Cache Latch冲突优化 (文档 ID 1523934.1)

原文链接:https://support.oracle.com/epmos/faces/DocumentDisplay?_adf.ctrlstate=23w4l35u5_4&id=1523934.1用途   提出问题,得到帮助并分享您的心得   排错步骤   什么是shared pool?   专用术语   Literal SQL   Hard Parse(硬解析)   Soft Parse(软解析)   完全相同的语句?   Sharable SQL   语句的版本   Library Cac

【SQL 调优】绑定变量窥测

绑定变量窥测:在物理优化阶段,查询优化器会窥测绑定变量的值,将它作为文本来使用.这种方法的问题是它生成的执行计划会依赖第一次生成执行计划时所提供的值.--建立索引                                                                           SQL> create index i_obj_id on t_var_peek(object_id); 索引已创建. 已用时间:  00: 00: 00.25 ---执行计划选择了 ra