Adaptive Cursor Sharing(第四篇)

ACS与PL/SQL

前面的章节论述了ACS的特性,我们来看下ACS在PL/SQL里的工作情况,结果可能会令你非常失望。

首先构造一个PL/SQL,里面使用到了我们在本章中创建的表T:

SQL>var sql_id varchar2(255)

SQL>alter system flush shared_pool;

System altered.

SQL>declare

  2    x integer;

  3    n number;

  4  begin

  5    for i in 1..10 loop

  6      if i = 1 then

  7        x := 500000;

  8      else

  9        x := 1;

 10      end if;

 11  select count(object_id) into n from t where id > x;

 12    end loop;

 13  end;

 14  /

PL/SQL procedure successfully completed.

这段PL/SQL首先会执行‘select count(object_id) into n from t where id > 100000 ’1次,然后会执行‘select count(object_id) into n from t where id >1’ 9次,执行完成后,我们来看看是否会使用到ACS。

SQL>select

  2          sql_id

  3        , child_number

  4        , executions

  5        , parse_calls

  6        , buffer_gets

  7        , is_bind_sensitive

  8        , is_bind_aware

  9  from

 10          v$sql

 11  where

 12          sql_id =' gp03v5aw085v3';

SQL_ID          CHILD_NUMBER EXECUTIONS PARSE_CALLS BUFFER_GETS IS IS

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

gp03v5aw085v3              0         10           1      646875 Y  N

非常可惜,这个SQL并没有产生多个子游标,虽然已经识别到这个SQL为绑定敏感is_bind_sensitive='Y',但是is_bind_aware='N'。

SQL> SELECT   hash_value, sql_id, child_number, bucket_id, COUNT

  2           FROM v$sql_cs_histogram

  3         WHERE sql_id='gp03v5aw085v3'

  4       ORDER BY sql_id, child_number;

HASH_VALUE SQL_ID          CHILD_NUMBER  BUCKET_ID      COUNT

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

3087275875 gp03v5aw085v3              0          0          1

3087275875 gp03v5aw085v3              0          2          9

3087275875 gp03v5aw085v3              0          1          0

虽然v$sql_cs_histogram已经监控到了处理行数的巨大改变,但是却没有生成新的游标。


SQL>select * from table(dbms_xplan.display_cursor(:sql_id,null,'+PEEKED_BINDS'));

PLAN_TABLE_OUTPUT

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

SQL_ID  gp03v5aw085v3, child number 0

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

SELECT COUNT(OBJECT_ID) FROM T WHERE ID > :B1

Plan hash value: 3694077449

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

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

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

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

|   1 |  SORT AGGREGATE              |      |     1 |    10 |            |          |

|   2 |   TABLE ACCESS BY INDEX ROWID| T    |     1 |    10 |     4   (0)| 00:00:01 |

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

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

Peeked Binds (identified by position):

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

   1 - :B1 (NUMBER): 5000000

Predicate Information (identified by operation id):

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

   3 - access("ID">:B1)

执行计划一直沿用的是第一次产生的执行计划,根据Peeked Binds (identified by position):的值为5000000可以推断出来。我们尝试在SQL里增加bind_aware hint看看,这个hint的作用在本章的最佳实践小节中介绍,这里不再赘述。

SQL>declare

  2    x integer;

  3    n number;

  4  begin

  5    for i in 1..10 loop

  6      if i = 1 then

  7        x := 5000000;

  8      else

  9        x := 1;

 10      end if;

 11  select /*+ bind_aware */count(object_id) into n from t where id > x;

 12    end loop;

 13  end;

 14  /

PL/SQL procedure successfully completed.

SQL>select

  2          sql_id

  3        , child_number

  4        , executions

  5        , parse_calls

  6        , buffer_gets

  7        , is_bind_sensitive

  8        , is_bind_aware

  9  from

 10          v$sql

 11  where

 12          sql_id = '5542a2rzny69v';

SQL_ID          CHILD_NUMBER EXECUTIONS PARSE_CALLS BUFFER_GETS IS IS

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

5542a2rzny69v              0         10           1      687396 Y  Y

虽然优化器已经标记这个游标is_bind_aware='Y'了,但是依然没有新的游标产生出来。在MOS上查找类似的问题,会发现一个BUG:
Bug 8357294 : ADAPTIVE cursor SHARING DOESN'T WORK FOR STATIC SQL cursorS FROM PL/SQL
标题的意思是由于BUG,ACS不能工作在PL/SQL的静态游标里。但是根据测试动态游标也不能工作。

SQL>declare

  2    x integer;

  3    n number;

  4  begin

  5    for i in 1..10 loop

  6      if i = 1 then

  7        x := 5000000;

  8      else

  9        x := 1;

 10      end if;

 11      execute immediate 

 12  'select count(object_id)  from t where id > :x' into n using x;

 13    end loop;

 14  end;

 15  /

PL/SQL procedure successfully completed.

SQL>select

  2          sql_id

  3        , child_number

  4        , executions

  5        , parse_calls

  6        , buffer_gets

  7        , is_bind_sensitive

  8        , is_bind_aware

  9  from

 10          v$sql

 11  where

 12          sql_id = '6qwg6gauwbpm8';

SQL_ID          CHILD_NUMBER EXECUTIONS PARSE_CALLS BUFFER_GETS IS IS

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

6qwg6gauwbpm8              0         10           1      687580 Y  N

文中提到了Session_Cached_Cursors在设置为0后,ACS就可以正常工作了,经过试验也如它所说。

SQL>alter session set Session_Cached_Cursors=0;

Session altered.

SQL>alter system flush shared_pool;

System altered.

SQL>declare

  2    x integer;

  3    n number;

  4  begin

  5    for i in 1..10 loop

  6      if i = 1 then

  7        x := 5000000;

  8      else

  9        x := 1;

 10      end if;

 11  select count(object_id) into n from t where id > x;

 12    end loop;

 13  end;

 14  /

PL/SQL procedure successfully completed.

SQL>select

  2          sql_id

  3        , child_number

  4        , executions

  5        , parse_calls

  6        , buffer_gets

  7        , is_bind_sensitive

  8        , is_bind_aware

  9  from

 10          v$sql

 11  where

 12          sql_id = ' gp03v5aw085v3';

SQL_ID          CHILD_NUMBER EXECUTIONS PARSE_CALLS BUFFER_GETS IS IS

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

gp03v5aw085v3              0          2           3       76405 Y  N

gp03v5aw085v3              1          8           7      517480 Y  Y

SQL>select * from table(dbms_xplan.display_cursor('gp03v5aw085v3',null));

PLAN_TABLE_OUTPUT

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

SQL_ID  gp03v5aw085v3, child number 0

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

SELECT COUNT(OBJECT_ID) FROM T WHERE ID > :B1

Plan hash value: 3694077449

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

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

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

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

|   1 |  SORT AGGREGATE              |      |     1 |    10 |            |          |

|   2 |   TABLE ACCESS BY INDEX ROWID| T    |     1 |    10 |     4   (0)| 00:00:01 |

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

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

Predicate Information (identified by operation id):

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

   3 - access("ID">:B1)

SQL_ID  gp03v5aw085v3, child number 1

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

SELECT COUNT(OBJECT_ID) FROM T WHERE ID > :B1

Plan hash value: 2966233522

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

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

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

|   0 | SELECT STATEMENT   |      |       |       | 14373 (100)|          |

|   1 |  SORT AGGREGATE    |      |     1 |    10 |            |          |

|*  2 |   TABLE ACCESS FULL| T    |  4999K|    47M| 14373   (2)| 00:02:53 |

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

Predicate Information (identified by operation id):

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

   2 - filter("ID">:B1)

可以看到ACS已经工作了,在v$sql_cs_histogram里也为新游标产生了新的行。

SQL> SELECT   hash_value, sql_id, child_number, bucket_id, COUNT

  2      FROM v$sql_cs_histogram

  3    WHERE sql_id='gp03v5aw085v3'

  4  ORDER BY sql_id, child_number;

HASH_VALUE SQL_ID          CHILD_NUMBER  BUCKET_ID      COUNT

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

3087275875 gp03v5aw085v3              0          1          0

3087275875 gp03v5aw085v3              0          0          1

3087275875 gp03v5aw085v3              0          2          1

3087275875 gp03v5aw085v3              1          1          0

3087275875 gp03v5aw085v3              1          0          0

3087275875 gp03v5aw085v3              1          2          8

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/22034023/viewspace-2153690/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/22034023/viewspace-2153690/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码下载:完整代码,可直接运行 ;运行版本:2022a或2019b或2014a;若运行有问题,可私信博主; **仿真咨询 1 各类智能优化算法改进及应用** 生产调度、经济调度、装配线调度、充电优化、车间调度、发车优化、水库调度、三维装箱、物流选址、货位优化、公交排班优化、充电桩布局优化、车间布局优化、集装箱船配载优化、水泵组合优化、解医疗资源分配优化、设施布局优化、可视域基站和无人机选址优化 **2 机器学习和深度学习方面** 卷积神经网络(CNN)、LSTM、支持向量机(SVM)、最小二乘支持向量机(LSSVM)、极限学习机(ELM)、核极限学习机(KELM)、BP、RBF、宽度学习、DBN、RF、RBF、DELM、XGBOOST、TCN实现风电预测、光伏预测、电池寿命预测、辐射源识别、交通流预测、负荷预测、股价预测、PM2.5浓度预测、电池健康状态预测、水体光学参数反演、NLOS信号识别、地铁停车精准预测、变压器故障诊断 **3 图像处理方面** 图像识别、图像分割、图像检测、图像隐藏、图像配准、图像拼接、图像融合、图像增强、图像压缩感知 **4 路径规划方面** 旅行商问题(TSP)、车辆路径问题(VRP、MVRP、CVRP、VRPTW等)、无人机三维路径规划、无人机协同、无人机编队、机器人路径规划、栅格地图路径规划、多式联运运输问题、车辆协同无人机路径规划、天线线性阵列分布优化、车间布局优化 **5 无人机应用方面** 无人机路径规划、无人机控制、无人机编队、无人机协同、无人机任务分配 **6 无线传感器定位及布局方面** 传感器部署优化、通信协议优化、路由优化、目标定位优化、Dv-Hop定位优化、Leach协议优化、WSN覆盖优化、组播优化、RSSI定位优化 **7 信号处理方面** 信号识别、信号加密、信号去噪、信号增强、雷达信号处理、信号水印嵌入提取、肌电信号、脑电信号、信号配时优化 **8 电力系统方面** 微电网优化、无功优化、配电网重构、储能配置 **9 元胞自动机方面** 交通流 人群疏散 病毒扩散 晶体生长 **10 雷达方面** 卡尔曼滤波跟踪、航迹关联、航迹融合

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值