您的位置:首页 > 数据库 > Oracle

Oracle_自适应游标共享的整体执行流程

2015-08-16 16:36 501 查看
Oracle 自适应游标共享的整体执行流程,如下:

1、当目标SQL第一次被执行时,Oracle会用硬解析,同时Oracle会根据一系列条件(如:SQL有没有使用绑定变量,参数cursor_shared的值是什么,绑定变量所在

列是否有直方图,该sql的where条件是等值查询还是范围查询等),来判断是否将该SQL所对应的child cursor标记为bind sensitive,对于标记为bind sensitive的child

cursor ,oracle 会把执行该sql时所对应的runtime统计信息额外地存储在该sql所对应的child cursor中。

    查询视图:select SQL_ID,CHILD_NUMBER,IS_BIND_SENSITIVE ,IS_BIND_AWARE,IS_SHAREABLE from v$sql where sql_id='bkpynbfzkjxnu'

2、当目标SQL 第二次被执行时,Oracle会用软解析,并且会重用该SQL第一次执行时所产生的child cursor中存储的解析树和执行计划。

3、当目标SQL第三次被执行时,如果该sql所对应的child cursor已经被标记成了 bind sensitive,同时oracle在第二次和第三次执行该sql时所记录的runtime统计信息和该SQL第一次硬解析时差异较大,这是会使用硬解析。

4、对于标记为bind aware的child cursor所对应的目标SQL,当该SQL再次被执行时,oracle会自动判断,是采用硬解析还是软解析。

下面,我们对自适应游标共享的示例进行测试。

1、创建测试表

       create table sdxj.t4 as select * from dba_objects;

2、创建索引

      create index sdxj.idx_t4 on sdxj.t4 (object_type);

3、修改数据使其数据不均匀分布

      update sdxj.t4 set object_type='TABLE' WHERE ROWNUM<60000;

      update sdxj.t4 set object_type='CLUSTER' WHERE ROWNUM<2;

4、查询结果

      SQL> SELECT COUNT(*) FROM SDXJ.T4;

     COUNT(*)

     ----------

     72446

     SQL> SELECT COUNT(*) FROM sdxj.t4 WHERE  object_type='CLUSTER';

     COUNT(*)

     -------

         1

     SQL> SELECT COUNT(*) FROM sdxj.t4 WHERE  object_type='TABLE';

    COUNT(*)

    ----------

     61525

5、收集表T4直方图信息

     exec dbms_stats.gather_table_stats(ownname => 'SDXJ',tabname => 'T4',estimate_percent => 100,CASCADE => TRUE,no_invalidate  => FALSE,method_opt => 'for all columns size auto',degree => 16);

6、查看收集结果

    sql>select LOW_VALUE,HIGH_VALUE,LAST_ANALYZED,NUM_BUCKETS, HISTOGRAM from DBA_TAB_COL_STATISTICS where owner='SDXJ' AND TABLE_NAME='T4'  AND COLUMN_NAME='OBJECT_TYPE';

LOW_VALUE                                                        HIGH_VALUE                                               LAST_ANALYZED  NUM_BUCKETS HISTOGRAM

---------------------------------------------------------------- ---------------------------------------------------------------- -------------- ----------- --

434C5553544552                                                   584D4C20534348454D41                                     16-8月 -15              30 FREQUENCY

7、进行测试

   在测试之前保持隐含参数 _OPTIM_PEEK_USER_BINDS 和 CURSOR_SHARING为默认值。

   sql> alter system flush shared_pool   ---生产环境禁止操作。

   

定义变量x 并进行赋值

sql> var x varchar2(30);

sql> exec :x :='CLUSTER';

sql>select count(*) from sdxj.t4 where object_type=:x;

sql>SELECT  SQL_TEXT,SQL_ID,VERSION_COUNT ,executions,ADDRESS,HASH_VALUE FROM V$SQLAREA WHERE SQL_TEXT LIKE 'SELECT COUNT(*) FROM SDXJ.T4 WHERE OBJECT%';

SQL_TEXT                                           SQL_ID                                             VERSION_COUNT EXECUTIONS ADDRESS  HASH_VALUE

-------------------------------------------------- -------------------------------------------------- ------------- ---------- -------- ----------

SELECT COUNT(*) FROM SDXJ.T4 WHERE OBJECT_TYPE=:X  b7yj2ja74bygg                                          1          1 B4E68BB4 2386950639

SQL> SELECT CHILD_NUMBER,EXECUTIONS,BUFFER_GETS,IS_BIND_SENSITIVE ,IS_BIND_AWARE,IS_SHAREABLE,PLAN_HASH_VALUE  FROM V$SQL WHERE SQL_ID='b7yj2ja74bygg';

目标sql执行计划

Plan hash value: 1219564997

---------------------------------------------------------------------------

| Id  | Operation         | Name   | Rows  | Bytes | Cost (%CPU)| Time

---------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |        |       |       |     3 (100)|

|   1 |  SORT AGGREGATE   |        |     1 |     7 |            |

PLAN_TABLE_OUTPUT

---------------------------------------------------------------------------

|*  2 |   INDEX RANGE SCAN| IDX_T4 |     1 |     7 |     3   (0)| 00:00:01

---------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):

-------------------------------------------------------------

   1 - SEL$1

   2 - SEL$1 / T4@SEL$1

Outline Data

------------

PLAN_TABLE_OUTPUT

---------------------------------------------------------------------------

  /*+

      BEGIN_OUTLINE_DATA

      IGNORE_OPTIM_EMBEDDED_HINTS

      OPTIMIZER_FEATURES_ENABLE('11.2.0.1')

      DB_VERSION('11.2.0.1')

      ALL_ROWS

      OUTLINE_LEAF(@"SEL$1")

      INDEX(@"SEL$1" "T4"@"SEL$1" ("T4"."OBJECT_TYPE"))

      END_OUTLINE_DATA

  */

PLAN_TABLE_OUTPUT

---------------------------------------------------------------------------

Peeked Binds (identified by position):

--------------------------------------

   1 - :X (VARCHAR2(30), CSID=873): 'CLUSTER'

Predicate Information (identified by operation id):

---------------------------------------------------

   2 - access("OBJECT_TYPE"=:X)

PLAN_TABLE_OUTPUT

---------------------------------------------------------------------------

Column Projection Information (identified by operation id):

-----------------------------------------------------------

   1 - (#keys=0) COUNT(*)[22]

已选择49行。

现在将x 的值修改为 “Table"

SQL> exec :x :='TABLE'

PL/SQL 过程已成功完成。

SQL> SELECT COUNT(*) FROM SDXJ.T4 WHERE OBJECT_TYPE=:x;

  COUNT(*)

----------

     61525

Plan hash value: 2030376245

--------------------------------------------------------------------------------

| Id  | Operation             | Name   | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------------

|   0 | SELECT STATEMENT      |        |       |       |    83 (100)|          |

|   1 |  SORT AGGREGATE       |        |     1 |     7 |            |          |

|*  2 |   INDEX FAST FULL SCAN| IDX_T4 | 61525 |   420K|    83   (2)| 00:00:01 |

--------------------------------------------------------------------------------

Query Block Name / Object Alias (identified by operation id):

-------------------------------------------------------------

   1 - SEL$1

   2 - SEL$1 / T4@SEL$1

Outline Data

-------------

  /*+

      BEGIN_OUTLINE_DATA

      IGNORE_OPTIM_EMBEDDED_HINTS

      OPTIMIZER_FEATURES_ENABLE('11.2.0.1')

      DB_VERSION('11.2.0.1')

      ALL_ROWS

      OUTLINE_LEAF(@"SEL$1")

      INDEX_FFS(@"SEL$1" "T4"@"SEL$1" ("T4"."OBJECT_TYPE"))

      END_OUTLINE_DATA

  */

Peeked Binds (identified by position):

--------------------------------------

   1 - :X (VARCHAR2(30), CSID=873): 'TABLE'

Predicate Information (identified by operation id):

---------------------------------------------------

   2 - filter("OBJECT_TYPE"=:X)

Column Projection Information (identified by operation id):

-----------------------------------------------------------

   1 - (#keys=0) COUNT(*)[22]

已选择49行。

sql>select child_number,predicate,range_id,low,high from v$sql_cs_selectivity where sql_id='dg8wsunwkvq57';

selecttivity =bucketsize /num_rows

解释:

a、上述计算公式适用于启用了绑定变量窥探,目标列有Frequency 类型的直方图,对目标施行等值查询条件

并且查询条件的输入值等于该列的某个实际值时的计算。

b、num_rows 表示目标列所在表的记录数

c、bucketsize 表示目标列的某个实际值所对应的记录数。

--实际计算结果:

SELECT ROUND((61525/72446)*0.9,6),ROUND((61525/72446)*1.1,6)  FROM DUAL;

###禁用自适用游标共享。

1、将隐含参数_optimizer_extended_cursor_sharing 和_optimizer_extended_cursor_sharing——的值改为NONE

2、将隐含参数 _optimizer_adaptive_cursor_sharing 的值设为false, 一旦隐含参数被设置为false 则所以的child cursor都将不能被标记为bind aware.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  sql 索引 数据库 优化