[20120420]11GR2新特性ACS的使用问题.txt

[20120420]11GR2新特性ACS的使用问题.txt

11GR2中采用Adaptive Cursor Sharing一定程度解决了bind peeking的问题。在我的测试中遇到一些问题,自己写一个例子测试如下:

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 id1,FLOOR(SQRT(ROWNUM)) id2 ,'test' NAME FROM DUAL CONNECT BY LEVEL
SQL> insert into t1 select rownum+9999,100 ,'test' NAME FROM DUAL CONNECT BY LEVEL
SQL> create index i_t1_id2 on t1(id2);
Index created.

BEGIN
  SYS.DBMS_STATS.GATHER_TABLE_STATS (
      OwnName        => user
     ,TabName        => 'T1'
    ,Estimate_Percent  => NULL
    ,Method_Opt        => 'FOR COLUMNS ID2 SIZE 254'
    ,Degree            => 4
    ,Cascade           => TRUE
    ,No_Invalidate     => TRUE);
END;
/
SQL> column low_value format a10
SQL> column high_value format a10
SQL> column data_type format a10
SQL> select column_name,data_type,num_distinct,low_value,high_value,num_buckets,histogram from dba_tab_cols where wner=user and table_name='T1';
COLUMN_NAME                    DATA_TYPE  NUM_DISTINCT LOW_VALUE  HIGH_VALUE NUM_BUCKETS HISTOGRAM
------------------------------ ---------- ------------ ---------- ---------- ----------- ---------------
ID1                            NUMBER            19998 C102       C3026463             1 NONE
ID2                            NUMBER              100 C102       C202               100 FREQUENCY
NAME                           CHAR                  1 74657374   74657374             1 NONE
SQL>
--可以发现ID2建立的直方图是FREQUENCY直方图。
SQL> column ENDPOINT_ACTUAL_VALUE format a10
SQL> column COLUMN_NAME  format a10
SQL> column owner format a10
SQL> column table_name format a10
SQL> select * from dba_tab_histograms where wner=user and table_name='T1' and column_name='ID2';
OWNER      TABLE_NAME COLUMN_NAM ENDPOINT_NUMBER ENDPOINT_VALUE ENDPOINT_A
---------- ---------- ---------- --------------- -------------- ----------
SCOTT      T1         ID2                      3              1
SCOTT      T1         ID2                      8              2
SCOTT      T1         ID2                     15              3
SCOTT      T1         ID2                     24              4
SCOTT      T1         ID2                     35              5
SCOTT      T1         ID2                     48              6
SCOTT      T1         ID2                     63              7
SCOTT      T1         ID2                     80              8
SCOTT      T1         ID2                     99              9
SCOTT      T1         ID2                    120             10
....
SCOTT      T1         ID2                   7920             88
SCOTT      T1         ID2                   8099             89
SCOTT      T1         ID2                   8280             90
SCOTT      T1         ID2                   8463             91
SCOTT      T1         ID2                   8648             92
SCOTT      T1         ID2                   8835             93
SCOTT      T1         ID2                   9024             94
SCOTT      T1         ID2                   9215             95
SCOTT      T1         ID2                   9408             96
SCOTT      T1         ID2                   9603             97
SCOTT      T1         ID2                   9800             98
SCOTT      T1         ID2                   9999             99
SCOTT      T1         ID2                  19998            100
100 rows selected.

2.检查与建立测试脚本,适当编辑一下:

set head off trimout on trimspool on
column a format a100
spool acs.sql
select 'set termout off'  a from dual 
union all
select 'variable a number;' a from dual
union all
select 'exec :a :='||rownum||';'||chr(10)||'select * from t1 where id2= :a;' a from dual connect by level
union all
select 'exec :a :='||'100;' a from  dual
union all
select 'select * from t1 where id2= :a;' a from dual connect by level
union all
select 'set termout on'  a from dual ;

--产生的sql脚本中:a=100的执行了108+1次,其他情况的执行了109次,两种正好相等。
--并且在脚本执行顺序上是最后执行:a := 100的语句执行108次。

3.调用acs.sql并执行它,很明显在:a 100时选择使用索引是最好的执行计划,而等于:a :=100 选择全表扫描最佳。

SQL> host cat dpc.sql
select * from table(dbms_xplan.display_cursor(NULL,NULL,'ALLSTATS LAST PEEKED_BINDS cost'));
SQL> alter system flush shared_pool;
System altered.
SQL> show parameter cursor_sharing
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------------------------------------
cursor_sharing                       string      EXACT
SQL
SQL> @acs.sql
SQL> @dpc.sql
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  01yvuvyfm4fhb, child number 0
-------------------------------------
select * from t1 where id2= :a
Plan hash value: 3984699272
----------------------------------------------------------------------
| Id  | Operation                   | Name     | E-Rows | Cost (%CPU)|
----------------------------------------------------------------------
|   0 | SELECT STATEMENT            |          |        |     2 (100)|
|   1 |  TABLE ACCESS BY INDEX ROWID| T1       |      3 |     2   (0)|
|*  2 |   INDEX RANGE SCAN          | I_T1_ID2 |      3 |     1   (0)|
----------------------------------------------------------------------
Peeked Binds (identified by position):
--------------------------------------
   1 - (NUMBER): 1
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("ID2"=: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.

--可以发现执行计划还是使用索引.并且知道sql_id='01yvuvyfm4fhb'.

SQL> @ share 01yvuvyfm4fhb
old  15:           and q.sql_id like ''&1''',
new  15:           and q.sql_id like ''01yvuvyfm4fhb''',
SQL_TEXT                       = select * from t1 where id2= :a
SQL_ID                         = 01yvuvyfm4fhb
ADDRESS                        = 00000000997A7898
CHILD_ADDRESS                  = 000000009363BCF0
CHILD_NUMBER                   = 0
LOAD_OPTIMIZER_STATS           = Y
--------------------------------------------------
PL/SQL procedure successfully completed.

--可以发现仅仅存在一个子光标。并没有产生2个光标!

4.查看与ACS有关的试图:

SQL> select * from V$SQL_CS_SELECTIVITY where sql_id='01yvuvyfm4fhb';
no rows selected
SQL> select * from V$SQL_CS_HISTOGRAM where sql_id='01yvuvyfm4fhb';
ADDRESS          HASH_VALUE SQL_ID        CHILD_NUMBER  BUCKET_ID      COUNT
---------------- ---------- ------------- ------------ ---------- ----------
00000000997A7898 2637314571 01yvuvyfm4fhb            0          0        109
00000000997A7898 2637314571 01yvuvyfm4fhb            0          1        109
00000000997A7898 2637314571 01yvuvyfm4fhb            0          2          0
SQL> select * from V$SQL_CS_STATISTICS where sql_id='01yvuvyfm4fhb';
ADDRESS          HASH_VALUE SQL_ID        CHILD_NUMBER BIND_SET_HASH_VALUE P EXECUTIONS ROWS_PROCESSED BUFFER_GETS   CPU_TIME
---------------- ---------- ------------- ------------ ------------------- - ---------- -------------- ----------- ----------
00000000997A7898 2637314571 01yvuvyfm4fhb            0           336594526 N          1          19998         146          0
00000000997A7898 2637314571 01yvuvyfm4fhb            0          2342552567 Y          1              6          71          0
00000000997A7898 2637314571 01yvuvyfm4fhb            0          1237562873 N          1             42           5          0

-- 从V$SQL_CS_HISTOGRAM看sql_id='01yvuvyfm4fhb',蓝色部分都是109次。
--换一句话讲如果在具体应用中如果执行:a :=100的次数不超过其他数据的执行次数,ACS将不会生效。

5.我们再执行一次:a:=100的情况看看。

SQL> exec :a :=100;
PL/SQL procedure successfully completed.
SQL> select * from t1 where id2= :a;
SQL> @dpc
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  01yvuvyfm4fhb, child number 1
-------------------------------------
select * from t1 where id2= :a
Plan hash value: 3617692013
--------------------------------------------------------
| Id  | Operation         | Name | E-Rows | Cost (%CPU)|
--------------------------------------------------------
|   0 | SELECT STATEMENT  |      |        |    16 (100)|
|*  1 |  TABLE ACCESS FULL| T1   |   9999 |    16   (0)|
--------------------------------------------------------
Peeked Binds (identified by position):
--------------------------------------
   1 - (NUMBER): 100
Predicate Information (identified by operation id):
--------------------------------------------------
   1 - filter("ID2"=: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
29 rows selected.

--可以发现现在才出现全表扫描的执行计划。

SQL> column sql_text format a30
SQL> column is_obsolete format a10
SQL> column is_bind_aware format a10
SQL> column is_shareable format a10
SQL> column is_bind_aware format a10
SQL> SELECT sql_text, sql_id, child_number,executions, plsql_exec_time, is_obsolete, is_bind_sensitive, is_bind_aware, is_shareable from v$sql where sql_id='01yvuvyfm4fhb';
SQL_TEXT                       SQL_ID        CHILD_NUMBER EXECUTIONS PLSQL_EXEC_TIME IS_OBSOLET I IS_BIND_AW IS_SHAREAB
------------------------------ ------------- ------------ ---------- --------------- ---------- - ---------- ----------
select * from t1 where id2= :a 01yvuvyfm4fhb            0        218               0 N          Y N          Y
select * from t1 where id2= :a 01yvuvyfm4fhb            1          1               0 N          Y Y          Y
SQL> exec :a :=99;
PL/SQL procedure successfully completed.
SQL> select * from t1 where id2= :a;
SQL> @dpc
SQL> @dpc
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------
SQL_ID  01yvuvyfm4fhb, child number 2
-------------------------------------
select * from t1 where id2= :a
Plan hash value: 3984699272
----------------------------------------------------------------------
| Id  | Operation                   | Name     | E-Rows | Cost (%CPU)|
----------------------------------------------------------------------
|   0 | SELECT STATEMENT            |          |        |     2 (100)|
|   1 |  TABLE ACCESS BY INDEX ROWID| T1       |    199 |     2   (0)|
|*  2 |   INDEX RANGE SCAN          | I_T1_ID2 |    199 |     1   (0)|
----------------------------------------------------------------------
Peeked Binds (identified by position):
--------------------------------------
   1 - (NUMBER): 99
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("ID2"=: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.
SQL> SELECT sql_text, sql_id, child_number,executions, plsql_exec_time, is_obsolete, is_bind_sensitive, is_bind_aware, is_shareable from v$sql where sql_id='01yvuvyfm4fhb';
SQL_TEXT                       SQL_ID        CHILD_NUMBER EXECUTIONS PLSQL_EXEC_TIME IS_OBSOLET I IS_BIND_AW IS_SHAREAB
------------------------------ ------------- ------------ ---------- --------------- ---------- - ---------- ----------
select * from t1 where id2= :a 01yvuvyfm4fhb            0        218               0 N          Y N          N
select * from t1 where id2= :a 01yvuvyfm4fhb            1          1               0 N          Y Y          Y
select * from t1 where id2= :a 01yvuvyfm4fhb            2          1               0 N          Y Y          Y
--可以发现child_number=0的is_shareable='N',不再共享。最后将被淘汰出共享池。
6.查看与ACS有关的试图:
SQL> select * from V$SQL_CS_SELECTIVITY where sql_id='01yvuvyfm4fhb';
ADDRESS          HASH_VALUE SQL_ID        CHILD_NUMBER PREDICATE                                  RANGE_ID LOW        HIGH
---------------- ---------- ------------- ------------ ---------------------------------------- ---------- ---------- ----------
00000000997A7898 2637314571 01yvuvyfm4fhb            2 =A                                                0 0.008956   0.010946
00000000997A7898 2637314571 01yvuvyfm4fhb            1 =A                                                0 0.449977   0.549972
SQL> select * from V$SQL_CS_HISTOGRAM where sql_id='01yvuvyfm4fhb';
ADDRESS          HASH_VALUE SQL_ID        CHILD_NUMBER  BUCKET_ID      COUNT
---------------- ---------- ------------- ------------ ---------- ----------
00000000997A7898 2637314571 01yvuvyfm4fhb            2          0          1
00000000997A7898 2637314571 01yvuvyfm4fhb            2          1          0
00000000997A7898 2637314571 01yvuvyfm4fhb            2          2          0
00000000997A7898 2637314571 01yvuvyfm4fhb            1          0          0
00000000997A7898 2637314571 01yvuvyfm4fhb            1          1          1
00000000997A7898 2637314571 01yvuvyfm4fhb            1          2          0
00000000997A7898 2637314571 01yvuvyfm4fhb            0          0        109
00000000997A7898 2637314571 01yvuvyfm4fhb            0          1        109
00000000997A7898 2637314571 01yvuvyfm4fhb            0          2          0
9 rows selected.
SQL> select * from V$SQL_CS_STATISTICS where sql_id='01yvuvyfm4fhb';
ADDRESS          HASH_VALUE SQL_ID        CHILD_NUMBER BIND_SET_HASH_VALUE P EXECUTIONS ROWS_PROCESSED BUFFER_GETS   CPU_TIME
---------------- ---------- ------------- ------------ ------------------- - ---------- -------------- ----------- ----------
00000000997A7898 2637314571 01yvuvyfm4fhb            2          1937997561 Y          1            398           5          0
00000000997A7898 2637314571 01yvuvyfm4fhb            1           336594526 Y          1           9999         103          0
00000000997A7898 2637314571 01yvuvyfm4fhb            0           336594526 N          1          19998         146          0
00000000997A7898 2637314571 01yvuvyfm4fhb            0          2342552567 Y          1              6          71          0
00000000997A7898 2637314571 01yvuvyfm4fhb            0          1237562873 N          1             42           5          0

7.总结:
可以发现ACS在解决bind peeking上依旧存在一定的局限行,要解决它当然有许多方法。也许最好的方法还是加入提示/*+ BIND_AWARE */ .

时间: 2024-08-01 10:05:31

[20120420]11GR2新特性ACS的使用问题.txt的相关文章

Oracle 11gR2新特性--延迟段创建(Deferred Segment Creation)

Oracle 11gR2新特性--延迟段创建(Deferred Segment Creation) 真题1. 什么是延迟段创建(Deferred Segment Creation)? 答案:在Oracle 11.2中,当创建一个空表或者空分区时,为了加快创建速度,Oracle并不会立即分配初始段和空间,实际的表段(Table Segement)被延迟到第一行数据插入时创建.延迟段创建特性通过DEFERRED_SEGMENT_CREATION参数控制,默认为TRUE,表示开启该功能.延迟段创建可以

11gR2 新特性--待定的统计信息(Pending Statistic)

 11gR2 新特性--待定的统计信息(Pending Statistic) 11gr2开始,可以使用下面类型的操作来收集优化器统计信息:1.             自动发布收集的统计信息在收集操作结束以后(默认选项publish)2.             保存新的统计信息,并且待定(暂不发布pending) 这个特性可以将新收集的统计信息置为待定状态,所以可以先验证新统计信息的有效性然后再发布. 可以使用下面的命令来查看是否默认发布新的统计信息.sys@DAVID> SELECTDBMS

[20130915]12c新特性 varchar2支持32K长度.txt

[20130915]12c新特性 varchar2支持32K长度.txt oracle 12c以前如果字符串长度超过4000,必须使用blob或者clob类型.12c开始支持超过4000的字符串长度,提高一些应用的灵活性,达到32K,避免一些字段定义为clob,blob类型,提高处理能力. 但是12c默认的方式不支持大于4000的字符串长度,必须经过一些步骤升级完成,自己测试如下: SYS@test> @ver BANNER                                    

【11gR2新特性】extent延迟创建

在使用create table中的storage参数时,在11g和10g中表现的不一样,步骤如下: database 10g: SQL> create table tab10 (id char(1000),name char(1000)) storage (minextents 2) pctfree 50 pctused 20; Table created. SQL> select object_id,object_name from dba_objects where object_name

【11gR2新特性】密码区分大小写

oracle的11g以前的 版本中用户的密码是不区分大小写的,11g中用户的密码大小写敏感了. oracle 9i的情况 SQL*Plus: Release 9.2.0.8.0 - Production on Mon Jul 11 19:32:15 2011 Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.sys@>create user yang identified by yang; User create

【11gR2新特性】result cache 的三种模式

yang@rac1>show parameter result NAME                                 TYPE        VALUE ------------------------------------ ----------- ------- client_result_cache_lag              big integer 3000 client_result_cache_size             big integer 0 r

【11gR2新特性】DBMS_RESULT_CACHE管理结果缓存的包

Oracle 11g提供了DBMS_RESULT_CACHE包来查询SQL结果缓存内容的状态和适当地控制SQL结果缓存内容. DBMS_RESULT_CACHE功能和存储过程 功能/存储过程    描述 STATUS:  返回结果缓存的当前状态.值包括:      ENABLED: 结果缓存是激活的.      DISABLED:结果缓存是不可用的.      BYPASSED:结果缓存暂时不可用.      SYNC:    结果缓存是可用的,但是目前正与其他RAC节点重新同步. MEMORY

Oracle Database 12.2新特性详解

在2015年旧金山的Oracle OpenWorld大会上,Oracle发布了Database 12.2的Beta版本,虽然Beta版本只对部分用户开放,但是大会上已经公布了12.2的很多重要的新特性,云和恩墨是Oracle的Beta用户,已经开始测试这一产品.在刚刚结束的"Oracle技术嘉年华"大会上,更详细的主题分享披露了更多内容.在这篇文章中,我将和大家一一来细数Oracle Database 12.2的新特性. Oracle Sharding的实现 简单来说,Oracle的S

盘点 Oracle 11g 中新特性带来的10大性能影响

盘点 Oracle 11g 中新特性带来的10大性能影响 原创 2017-08-02 盖国强 数据和云 Oracle的任何一个新版本,总是会带来大量引人瞩目的新特性,但是往往在这些新特性引入之初,首先引起的是一些麻烦,因为对于新技术的不了解.因为对于旧环境的不适应,从Oracle产品到技术服务运维,总是要走过一个磨合的长期过程. 请注意:我们并不推荐大家盲目的关闭和摒弃Oracle的新特性,我们建议大家在遇到问题时,做出适合自己的调整. 就此盘点一下 Oracle 11g 中,那些新特性带来的新