oracle 12c自适应游标,Oracle 自适应游标共享–adaptive cursor sharing

在11g中,Oracle引入了一项新特征:adaptive cursor sharing 自适应游标共享。这项特征主要用来改进具有绑定变量的sql语句的执行

在11g中,Oracle引入了一项新特征:adaptive cursor sharing 自适应游标共享。这项特征主要用来改进具有绑定变量的sql语句的执行计划,也导致了具有绑定变量的sql语句可能会生成多个游标。在9i中,Oracle引入了变量窥测(bind peeking)技术,通过使用变量窥测在SQL语句第一次硬解析时,优化器可以判定where子句的选择性,从而改进生成执行计划的质量。但是使用变量窥测技术生成的执行计划在表数据分布不均衡的情况下,往往不具有通用性。(参见:)

自适应游标共享功能的引入,可以有效的解决这个问题。

首先看一下我们的测试环境:

SQL> desc acs_test_tab

名称 是否为空? 类型

—————————————————– ——– ————————————

ID NOT NULL NUMBER

RECORD_TYPE NUMBER

DESCRIPTION VARCHAR2(50)

SQL> select count(*) from acs_test_tab;

COUNT(*)

———-

100000

SQL> select count(*) from acs_test_tab where record_type=2;

COUNT(*)

———-

50000

SQL> select count(distinct record_type) from acs_test_tab;

COUNT(DISTINCTRECORD_TYPE)

————————–

50001

表acs_test_Tab在列record_type上分布式是倾斜的。收集统计信息:

SQL> exec dbms_stats.gather_Table_Stats(user,’acs_test_Tab’,cascade=>true,method_opt=>’for all columns size auto’);

PL/SQL 过程已成功完成。

SQL> select column_name,histogram from user_tab_cols where table_name=’ACS_TEST_TAB’;

COLUMN_NAME HISTOGRAM

—————————— —————

ID NONE

RECORD_TYPE HEIGHT BALANCED

DESCRIPTION NONE

首先我们对record_type 为1 的列进行查询

SQL> select count(*) from acs_test_tab where record_type = 1;

COUNT(*)

———-

1

SQL> alter system flush shared_pool;

系统已更改。

SQL> var v number;

SQL> exec :v := 1

PL/SQL 过程已成功完成。

SQL> select sum(id) from acs_test_tab where record_type = :v;

SUM(ID)

———-

1

SQL> select * from table(dbms_xplan.display_cursor);

PLAN_TABLE_OUTPUT

—————————————————————————————————————————————————————-

SQL_ID 3p66zbwtm19bs, child number 0

————————————-

select sum(id) from acs_test_tab where record_type = :v

Plan hash value: 3987223107

———————————————————————————————————–

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

———————————————————————————————————–

| 0 | SELECT STATEMENT | | | | 4 (100)| |

| 1 | SORT AGGREGATE | | 1 | 9 | | |

| 2 | TABLE ACCESS BY INDEX ROWID| ACS_TEST_TAB | 1 | 9 | 4 (0)| 00:00:01 |

|* 3 | INDEX RANGE SCAN | ACS_TEST_TAB_RECORD_TYPE_I | 1 | | 3 (0)| 00:00:01 |

———————————————————————————————————–

Predicate Information (identified by operation id):

—————————————————

3 – access(“RECORD_TYPE”=:V)

已选择20行。

SQL> select child_number,executions,buffer_gets,is_bind_sensitive,is_bind_aware

2 from v$sql

3 where sql_text like ‘select sum(id)%’;

CHILD_NUMBER EXECUTIONS BUFFER_GETS I I

———— ———- ———– – –

0 1 218 Y N

下面我们在查询一下record_type为2的记录,

SQL> exec :v := 2

PL/SQL 过程已成功完成。

SQL> select sum(id) from acs_test_tab where record_type = :v;

SUM(ID)

———-

2500050000

SQL> select * from table(dbms_xplan.display_cursor);

PLAN_TABLE_OUTPUT

—————————————————————————————————————————————————————-

SQL_ID 3p66zbwtm19bs, child number 0

————————————-

select sum(id) from acs_test_tab where record_type = :v

Plan hash value: 3987223107

———————————————————————————————————–

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

———————————————————————————————————–

| 0 | SELECT STATEMENT | | | | 4 (100)| |

| 1 | SORT AGGREGATE | | 1 | 9 | | |

| 2 | TABLE ACCESS BY INDEX ROWID| ACS_TEST_TAB | 1 | 9 | 4 (0)| 00:00:01 |

|* 3 | INDEX RANGE SCAN | ACS_TEST_TAB_RECORD_TYPE_I | 1 | | 3 (0)| 00:00:01 |

———————————————————————————————————–

Predicate Information (identified by operation id):

—————————————————

3 – access(“RECORD_TYPE”=:V)

已选择20行。

SQL> select child_number,executions,buffer_gets,is_bind_sensitive,is_bind_aware

2 from v$sql

3 where sql_text like ‘select sum(id)%’;

CHILD_NUMBER EXECUTIONS BUFFER_GETS I I

———— ———- ———– – –

0 2 832 Y N

我们发现执行计划没有变化,但是统计信息却发生了比较大的跳跃。

再次执行上面的语句

SQL> select sum(id) from acs_test_tab where record_type = :v;

SUM(ID)

———-

2500050000

SQL> select * from table(dbms_xplan.display_cursor);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值