为了不让其他因素干扰实验,参数设置如下:

optimizer_mode=ALL_ROWS(使用CBO)
optimizer_features_enable=11.2.0.3(使用最新的优化参数)
optimizer_capture_sql_plan_baselines=false(关闭SPM)
cursor_sharing=EXACT(使用真正的绑定变量)
_optim_peek_user_binds=true(一定要开启绑定变量窥视)
_optimizer_adaptive_cursor_sharing=TRUE(以下三个参数默认开启ACS)
_optimizer_extended_cursor_sharing=UDO
_optimizer_extended_cursor_sharing_rel=SIMPLE --查询隐含参数:
SELECT ksppinm, ksppstvl, ksppdesc
FROM sys.x$ksppi x, sys.x$ksppcv y
WHERE x.indx = y.indx AND ksppinm = '_optimizer_extended_cursor_sharing';

建立测试场景:

#创建表
SQL> create table tab_acs(id int,value int); #导入数据
SQL> begin
2 for i in 1 .. 20000
3 loop
4 execute immediate 'insert into tab_acs values(1,'||i||')';
5 end loop;
6 end;
7 /
PL/SQL procedure successfully completed. SQL> begin
2 for i in 1 .. 10
3 loop
4 execute immediate 'insert into tab_acs values(2,'||i||')';
5 end loop;
6 end;
7 /
PL/SQL procedure successfully completed.
SQL> commit; #创建索引
SQL> create index idx_tab_acs on tab_acs(id); #收集统计信息
SQL> exec dbms_stats.gather_table_stats(user,'TAB_ACS',method_opt=>'for all columns size skewonly');
#查看数据直方图分布
SQL> select COLUMN_NAME,HISTOGRAM from user_tab_columns where TABLE_NAME='TAB_ACS';
COLUMN_NAME HISTOGRAM
------------------------------ ---------------
ID FREQUENCY --等频直方图
VALUE NONE
SQL>

先生成一个最简单的执行计划index range scan

对于id=2来说,是相当合适的。
SQL> var v number;
SQL> exec :v :=2;
SQL> select /*comments*/ * from TAB_ACS
2 where id = :v; 查询SQL_ID,HASH_VALUE:
SQL> select sql_id, hash_value,sql_text from v$sql
2 where sql_text like '%from%TAB_ACS%';
SQL_ID HASH_VALUE SQL_TEXT
------------- ---------- --------------------------------------------------------------------------------
9s0fn2xffhk6z 1558726879 select /*comments*/ * from TAB_ACS where id = :v 获取真实的执行计划:
--SELECT * FROM table (DBMS_XPLAN.DISPLAY_CURSOR(:sqlid, NULL, 'TYPICAL LAST'))
SQL> SELECT * FROM table (DBMS_XPLAN.DISPLAY_CURSOR('9s0fn2xffhk6z', NULL, 'TYPICAL LAST'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID 9s0fn2xffhk6z, child number 0
-------------------------------------
select /*comments*/ * from TAB_ACS where id = :v
Plan hash value: 360359870
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 2 (100)|
| 1 | TABLE ACCESS BY INDEX ROWID| TAB_ACS | 10 | 70 | 2 (0)|
|* 2 | INDEX RANGE SCAN | IDX_TAB_ACS | 10 | | 1 (0)|
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"=:V)
19 rows selected SQL> 从v$SQL中,可以看到这个cursor的数据:
IS_BIND_SENSITIVE=Y,表明使用绑定变量窥视来生成这次执行计划,这次执行计划是取决于这个绑定变量的。如果Oracle发现有其他的绑定变量出现,是可能生成其他的执行计划的。
IS_BIND_AWARE=N,表明Oracle还没有使用extended cursor sharing
IS_SHAREABLE=Y,表明这个cursor可以被再次使用,即能够共享;反之,设为N代表着这个cursor已经过时了,不会被再用了,这个cursor将会等待被age out出shared pool。 SQL> select CHILD_NUMBER,PLAN_HASH_VALUE,EXECUTIONS,BUFFER_GETS/EXECUTIONS BG_PER_EX,IS_BIND_SENSITIVE BS,IS_BIND_AWARE BA,IS_SHAREABLE S
2 from v$sql where hash_value=1558726879;
CHILD_NUMBER PLAN_HASH_VALUE EXECUTIONS BG_PER_EX BS BA S
------------ --------------- ---------- ---------- -- -- -
0 360359870 1 16 Y N Y
SQL>
更换绑定变量,使用id=1执行同样的SQL.
SQL> exec :v := 1;
SQL> select /*comments*/ * from TAB_ACS
2 where id = :v; 结果,使用绑定变量id=1的SQL使用了同样的index range scan的cursor。这其实不是我们希望的,因为id=1时明显走全表扫描cost更低。
v$SQL没怎么变,只是同样的cursor执行次数为2了。 SQL> select CHILD_NUMBER,PLAN_HASH_VALUE,EXECUTIONS,BUFFER_GETS/EXECUTIONS BG_PER_EX,IS_BIND_SENSITIVE BS,IS_BIND_AWARE BA,IS_SHAREABLE S
2 from v$sql where hash_value=1558726879;
CHILD_NUMBER PLAN_HASH_VALUE EXECUTIONS BG_PER_EX BS BA S
------------ --------------- ---------- ---------- -- -- -
0 360359870 2 246 Y N Y
SQL>
--再次执行同样的id=1的SQL。
SQL> exec :v := 1;
SQL> select /*comments*/ * from TAB_ACS
2 where id = :v;
....... --获取sql_id,child_number,hash_value
SQL> select sql_id,child_number, hash_value,sql_text from v$sql
2 where sql_text like '%from%TAB_ACS%'; SQL_ID CHILD_NUMBER HASH_VALUE SQL_TEXT
------------- ------------ ---------- --------------------------------------------------------------------------------
9s0fn2xffhk6z 0 1558726879 select /*comments*/ * from TAB_ACS where id = :v
9s0fn2xffhk6z 1 1558726879 select /*comments*/ * from TAB_ACS where id = :v
SQL> --获取真是执行计划
SQL> SELECT * FROM table (DBMS_XPLAN.DISPLAY_CURSOR('9s0fn2xffhk6z', NULL, 'TYPICAL LAST'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
SQL_ID 9s0fn2xffhk6z, child number 1
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
select /*comments*/ * from TAB_ACS where id = :v
Plan hash value: 4258990176
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 17 (100)| |
|* 1 | TABLE ACCESS FULL| TAB_ACS | 20000 | 136K| 17 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("ID"=:V)
37 rows selected SQL> 终于,我们期望的事情发生了,新的全表扫描的执行计划产生了!(对应于CHILD_NUMBER=1,PLAN_HASH_VALUE=4258990176)
v$SQL里,新的cursor的IS_BIND_AWARE=
Y。 SQL> select SQL_ID,CHILD_NUMBER,PLAN_HASH_VALUE,EXECUTIONS,BUFFER_GETS/EXECUTIONS BG_PER_EX,IS_BIND_SENSITIVE BS,IS_BIND_AWARE BA,IS_SHAREABLE S
2 from v$sql where SQL_ID='9s0fn2xffhk6z'; SQL_ID CHILD_NUMBER PLAN_HASH_VALUE EXECUTIONS BG_PER_EX BS BA S
------------- ------------ --------------- ---------- ---------- -- -- -
9s0fn2xffhk6z 0 360359870 2 246 Y N N
9s0fn2xffhk6z 1 4258990176 1 266 Y Y Y SQL>
--再次执行id=1的SQL
SQL> exec :v := 1;
SQL> select /*comments*/ * from TESTBYHAO
2 where id = :v; CHILD 1执行次数增加为2
SQL> select SQL_ID,CHILD_NUMBER,PLAN_HASH_VALUE,EXECUTIONS,BUFFER_GETS/EXECUTIONS BG_PER_EX,IS_BIND_SENSITIVE BS,IS_BIND_AWARE BA,IS_SHAREABLE S
2 from v$sql where SQL_ID='9s0fn2xffhk6z';
SQL_ID CHILD_NUMBER PLAN_HASH_VALUE EXECUTIONS BG_PER_EX BS BA S
------------- ------------ --------------- ---------- ---------- -- -- -
9s0fn2xffhk6z 0 360359870 2 246 Y N N
9s0fn2xffhk6z 1 4258990176 2 266 Y Y Y SQL> 再次执行id=2的SQL
SQL> exec :v := 2;
SQL> select /*comments*/ * from TESTBYHAO
2 where id = :v; SQL> select SQL_ID,CHILD_NUMBER,PLAN_HASH_VALUE,EXECUTIONS,BUFFER_GETS/EXECUTIONS BG_PER_EX,IS_BIND_SENSITIVE BS,IS_BIND_AWARE BA,IS_SHAREABLE S
2 from v$sql where SQL_ID='9s0fn2xffhk6z';
SQL_ID CHILD_NUMBER PLAN_HASH_VALUE EXECUTIONS BG_PER_EX BS BA S
------------- ------------ --------------- ---------- ---------- -- -- -
9s0fn2xffhk6z 0 360359870 2 246 Y N N
9s0fn2xffhk6z 1 4258990176 2 266 Y Y Y
9s0fn2xffhk6z 2 360359870 1 4 Y Y Y SQL>
奇怪的事情发生了,又新生成了一个index range scan的cursor(CHILD ),并且CHILD 0的IS_SHAREABLE=N了,表明这个cursor不再被使用了。

自适应游标共享技术02(一个简单的例子来走近ACS)的更多相关文章

  1. 自适应游标共享技术01(Adaptive Cursor Sharing)

    什么是ACS(adaptiver cursor sharing) Oracle通过绑定变量技术解决了SQL语句硬解析过多的问题,降低了资源的争用.但是绑定变量在引入cursor sharing,增加了 ...

  2. Oracle 11g 新特性 -- 自适应游标共享(Adaptive Cursor Sharing: ACS) 说明(转载)

    一.自适应游标共享(Adaptive Cursor Sharing) 说明 1.1 ACS概述绑定变量使Oracle DB 可以为多条SQL 语句共享单个游标,以减少分析SQL 语句所使用的共享内存量 ...

  3. 利用HTML5与jQuery技术创建一个简单的自动表单完成

    来源:GBin1.com 在线演示   在线下载 谷歌快速搜索自带大量自动完成插件——库中甚至还有一个附带的jQuery UI共享选项.然而今天我要寻找一个替代的解决方案.由DevBridge开发的j ...

  4. 利用JSP编程技术实现一个简单的购物车程序

    实验二   JSP编程 一.实验目的1. 掌握JSP指令的使用方法:2. 掌握JSP动作的使用方法:3. 掌握JSP内置对象的使用方法:4. 掌握JavaBean的编程技术及使用方法:5. 掌握JSP ...

  5. Spring-Context之一:一个简单的例子

    很久之前就想系统的学习和掌握Spring框架,但是拖了很久都没有行动.现在趁着在外出差杂事不多,就花时间来由浅入深的研究下Spring框架.Spring框架这几年来已经发展成为一个巨无霸产品.从最初的 ...

  6. 用一个简单的例子来理解python高阶函数

    ============================ 用一个简单的例子来理解python高阶函数 ============================ 最近在用mailx发送邮件, 写法大致如 ...

  7. 关于apriori算法的一个简单的例子

    apriori算法是关联规则挖掘中很基础也很经典的一个算法,我认为很多教程出现大堆的公式不是很适合一个初学者理解.因此,本文列举一个简单的例子来演示下apriori算法的整个步骤. 下面这个表格是代表 ...

  8. 扩展Python模块系列(二)----一个简单的例子

    本节使用一个简单的例子引出Python C/C++ API的详细使用方法.针对的是CPython的解释器. 目标:创建一个Python内建模块test,提供一个功能函数distance, 计算空间中两 ...

  9. fitnesse - 一个简单的例子(slim)

    fitnesse - 一个简单的例子(slim) 2017-09-30 目录1 编写测试代码(Fixture code)2 编写wiki page并运行  2.1 新建wikiPage  2.2 运行 ...

随机推荐

  1. Oracle Grid Infrastructure: Understanding Split-Brain Node Eviction (文档 ID 1546004.1)

    In this Document   Purpose   Scope   Details   What does "split brain" mean?   Why is this ...

  2. List集合分组

    var ArticleList = new Services.Data.SearchService().GetArticleBaseList(ref param); IEnumerable<IG ...

  3. js对象3.1--什么是类,对象--杂志

    先来吹吹牛 大家都见过那种做的很精致的小蛋糕吧,给我的感觉就是(很精致,很好看,不经吃太少了,还忒TM的贵).那么这些蛋糕是怎么做出来的呢,反正我不相信是一个一个的扭出来的(除非老板不想赚钱了,那个一 ...

  4. Flex 列表控件中的操作

    主要操作包括:显示提示,使用图标,编辑列表条目中数据. 1.使用数据提示: 当鼠标停留在条目上时,可以显示该条目的相关数据提示. 当利用滚动条时,可以显示滚动条的相关提示. 在列表控件中使用showD ...

  5. How to deploy JAVA Application on Azure Service Fabric

    At this moment, Azure Service Fabric does not support JAVA application natively (but it's on the sup ...

  6. Eclipse 启动Tomcat后web项目的classes的子文件夹中没有calss文件

    Eclipse 启动Tomcat后web项目的classes的子文件夹中没有calss文件. 经网上查得以下方法可解决 把properties属性里的java compiler-->buildi ...

  7. 关于MPEG2中的图像序列和图像组头GOP

    图像序列 图像序列是由图像组构成的,是随机存取段落. sequence_header_code – The sequence_header_code is the bit string ‘000001 ...

  8. linux 关闭系统提示声音

    关闭Linux 提示声音:   rmmod pcspkr      //永久关闭 在/etc/modprobe.d/blacklist文件最后加上 blacklist pcspkr

  9. PowerDesigner之PDM检查

    一.PDM检查 1.检查项的设置 PDM错误级别分为Error和Warning两种.Error是致命错,一旦发现这类错误,系统会自动CDM生成PDM或者OOM,Warning是警告错误,是系统认为不合 ...

  10. 【Linux】Zabbix + MPM + msmtp + mutt 监控MySQL + 邮件报警

    Zabbix部署参考博文 http://blog.sina.com.cn/s/blog_5611597901017oe0.html  MPM安装配置参考博文和MPM官网下载地址 http://blog ...