返回顶部
首页 > 资讯 > 数据库 >Adaptive Cursor Sharing(第二篇)
  • 521
分享到

Adaptive Cursor Sharing(第二篇)

2024-04-02 19:04:59 521人浏览 泡泡鱼
摘要

选择率和硬解析 我们上面提到了,在v$sql_cs_histogram视图中,如果此游标的3个桶中出现了两个桶中的count都有非0值,那么此后的解析都要窥探绑定变量的值计算谓词选择率,如果计算选

选择率和硬解析

我们上面提到了,在v$sql_cs_histogram视图中,如果此游标的3个桶中出现了两个桶中的count都有非0值,那么此后的解析都要窥探绑定变量的值计算谓词选择率,如果计算选择率不在现有的游标的选择率范围内,就会基于窥探到的绑定变量的值重新硬解析产生一个新的游标,当然这个新游标的执行计划可能与之前是一样的。我们还是来看一个例子就会非常明白这种机制了。

SQL>create table t as select 1 id,a.* from dba_objects a,dba_objects b where rownum<10;

 

Table created.

 

SQL>create index t_ind on t(id);

 

Index created.

 

SQL>insert into t select 2,a.* from dba_objects a,dba_objects b where rownum<1000;

 

999 rows created.

 

SQL>insert into t select 3 ,a.* from dba_objects a,dba_objects b where rownum<10000;

 

9999 rows created.

 

SQL>insert into t select 4 ,a.* from dba_objects a,dba_objects b where rownum<100000;

 

99999 rows created.

 

SQL>insert into t select 5 ,a.* from dba_objects a,dba_objects b where rownum<1000000;

 

999999 rows created.

 

SQL>commit;

 

Commit complete.

SQL>begin

  2    dbms_stats.gather_table_stats(user,

  3                                  't',

  4                                  method_opt => 'for columns status size 5',

  5                                   cascade    => true);

  6    

  7  end;

  8  /

 

SQL>select id,count(*) from t group by id order by id;

 

        ID   COUNT(*)

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

         1          9

         2        999

         3       9999

         4      99999

         5     999999

上面的代码精心构造了一个例子,表t上的id字段一共有5个唯一值,每个值的数量都不一样,id字段上有索引,分析了直方图。在这种情况下,如果我们直接使用字符变量不使用绑定变量的话,id在对1,2,3,4做查询的时候,都会使用索引扫描,这种情况下,索引扫描的成本要比全表扫描的成本低,id在对5做查询时,会使用全表扫描,这种情况下全表扫描的成本要比索引扫描成本低。如下表格,我是通过explain工具,使用文本变量后,得出的每个执行计划的cost,可以看到全表扫描的cost为2911,在查询id<5的情况下,由于索引扫描的cost都小于全表扫描的cost因此执行计划都选择了走索引扫描,只有在查询id等于5的时,才选择了走全表扫描。

ID

执行计划

COST

选择率

1

索引扫描

4

0.0000081

2

索引扫描

16

0.000899186

3

索引扫描

139

0.008999959

4

索引扫描

1370

0.090007696

5

索引扫描

13690

0. 900085058

5

全表扫描

2911

0. 900085058

上面的表格最后一列提供了谓词的选择率,此处选择率的计算公式为:

选择率=id=?的值在表中的数量/总数量

根据上面表格的cost我们可以知道,谓词的选择率在0.0000081到0.090007696之间都应该选择索引扫描,在0. 900085058的时候应该选择全表扫描,因为id在5的时候,索引扫描的成本13690已经远远大于了全表扫描的成本2911。我们看看下面的例子:

SQL>var a number;

SQL>exec :a :=1;

 

PL/SQL procedure successfully completed.

 

SQL>select count(object_id) from t where id=:a;

 

COUNT(OBJECT_ID)

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

               9

 

SQL>exec :a :=5;

 

PL/SQL procedure successfully completed.

 

SQL>select count(object_id) from t where id=:a;

 

COUNT(OBJECT_ID)

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

          999999

 

SQL>select count(object_id) from t where id=:a;

 

COUNT(OBJECT_ID)

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

          999999

 

SQL>col PREDICATE for a10

SQL>-- 选择率

SQL>SELECT   hash_value, sql_id, child_number, predicate, range_id, low, high

  2      FROM v$sql_cs_selectivity

  3     WHERE sql_id='56g5zg95hcxc1'

ORDER BY sql_id, child_number;  4  

 

SQL_ID             CHILD_NUMBER PREDICATE    RANGE_ID LOW                  HIGH

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

56g5zg95hcxc1                 1 =A                  0 0.810076             0.990093

经过上面的一系列的操作后我们已经让这个cursor变得bind aware,如何让SQL变得bind aware我们上面已经论述过,这里不再做详细说明。经过这些步骤后,优化器已经产生出了一个child_number为1的新游标,这个游标基于绑定变量为5的值生成,谓词的选择率范围是:0.810076到0.990093。这个选择率跟我们上面表格里提供的选择率的关系是:(0.810076+0.990093)/2约等于我们上面表格里提供的选择率0. 900085058,oracle为选择率稍微的预留了一些余地,这样很好。我们再执行id为1的查询看看:

SQL>exec :a :=1;

 

PL/SQL procedure successfully completed.

 

SQL>select count(object_id) from t where id=:a;

 

COUNT(OBJECT_ID)

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

               9

 

SQL>-- 选择率

SQL>SELECT   hash_value, sql_id, child_number, predicate, range_id, low, high

  2      FROM v$sql_cs_selectivity

  3     WHERE sql_id='56g5zg95hcxc1'

ORDER BY sql_id, child_number;   

 

SQL_ID         CHILD_NUMBER PREDICATE    RANGE_ID LOW                  HIGH

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

56g5zg95hcxc1             1 =A                  0 0.810076             0.990093

56g5zg95hcxc1             2 =A                  0 0.000007             0.000009

已经产生了child_number为2的子游标,是基于id为1的值产生的,选择率范围为:0.000007到0.000009。下面就到了本节关键的时刻了,我们再次查询id为4看看会出现什么情况。

SQL>exec :a :=4

 

PL/SQL procedure successfully completed.

 

SQL>select count(object_id) from t where id=:a;

 

COUNT(OBJECT_ID)

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

           99999

 

SQL>

SQL>col PREDICATE for a10

SQL>-- 选择率

SQL>SELECT   hash_value, sql_id, child_number, predicate, range_id, low, high

  2      FROM v$sql_cs_selectivity

  3     WHERE sql_id='56g5zg95hcxc1'

  4  ORDER BY sql_id, child_number;

 

SQL_ID          CHILD_NUMBER PREDICATE    RANGE_ID LOW                  HIGH

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

56g5zg95hcxc1              1 =A                  0 0.810076             0.990093

56g5zg95hcxc1              2 =A                  0 0.000007             0.000009

56g5zg95hcxc1              3 =A                  0 0.000007             0.099008

 

SQL>SELECT child_number, executions, buffer_gets, is_bind_sensitive,  

  2        is_bind_aware,IS_SHAREABLE                                     

  3   FROM v$sql                                                          

  4  WHERE sql_id='56g5zg95hcxc1';                                        

 

CHILD_NUMBER EXECUTIONS BUFFER_GETS IS IS IS

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

           0          2       13690 Y  N  N

           1          1       13162 Y  Y  Y

           2          1           4 Y  Y  N

           3          1        1495 Y  Y  Y

优化器已经重新生成了一个child_numer为3的子游标,同时选择率的范围已经扩大了,从0.000007到0.099008,也就是现在从id为1到4都被包含在child_number为3的子游标里了。child_number为2的子游标已经被标记为不能共享失效了,如果共享池有紧缺这块内存就可以被清除出去。那是不是意味着我们查询id为3的值时,将不用重新产生新游标,直接可以使用child_number为3的子游标了。我们来看看:

SQL>exec :a :=3

 

PL/SQL procedure successfully completed.

 

SQL>col PREDICATE for a10

SQL>-- 选择率

SQL>SELECT   hash_value, sql_id, child_number, predicate, range_id, low, high

  2      FROM v$sql_cs_selectivity

  3     WHERE sql_id='56g5zg95hcxc1'

  4  ORDER BY sql_id, child_number;

 

SQL_ID          CHILD_NUMBER PREDICATE    RANGE_ID LOW                  HIGH

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

56g5zg95hcxc1              1 =A                  0 0.810076             0.990093

56g5zg95hcxc1              2 =A                  0 0.000007             0.000009

56g5zg95hcxc1              3 =A                  0 0.000007             0.099008

 

SQL>select count(object_id) from t where id=:a;

 

COUNT(OBJECT_ID)

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

            9999

 

SQL>-- 选择率

SQL>SELECT   hash_value, sql_id, child_number, predicate, range_id, low, high

  2      FROM v$sql_cs_selectivity

  3     WHERE sql_id='56g5zg95hcxc1'

  4  ORDER BY sql_id, child_number;

 

SQL_ID         CHILD_NUMBER PREDICATE    RANGE_ID LOW                  HIGH

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

56g5zg95hcxc1             1 =A                  0 0.810076             0.990093

56g5zg95hcxc1             2 =A                  0 0.000007             0.000009

56g5zg95hcxc1             3 =A                  0 0.000007             0.099008

 

SQL>SELECT child_number, executions, buffer_gets, is_bind_sensitive,  

  2        is_bind_aware,IS_SHAREABLE                                     

  3   FROM v$sql                                                          

  4  WHERE sql_id='56g5zg95hcxc1';                                        

 

CHILD_NUMBER EXECUTIONS BUFFER_GETS IS IS IS

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

           0          2       13690 Y  N  N

           1          1       13162 Y  Y  Y

           2          1           4 Y  Y  N

           3          2        1495 Y  Y  Y

没有再生成新的子游标了,同时v$sql中的child_number为3的子游标的执行次数已经加1了。

从上面的示例我们可以知道,在v$sql_cs_histogram视图中,如果此游标的3个桶中出现了两个桶中的count都有非0值,那么此后的解析都要窥探绑定变量的值计算谓词选择率,如果计算选择率不在现有的游标的选择率范围内,就会基于窥探到的绑定变量的值重新硬解析产生一个新的游标,记录此游标的可以代表的选择率范围,当然就像我们例子看到的,新游标的执行计划可能跟之前是一样的,只不过是选择率的范围更广了。

您可能感兴趣的文档:

--结束END--

本文标题: Adaptive Cursor Sharing(第二篇)

本文链接: https://lsjlt.com/news/49844.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Adaptive Cursor Sharing(第二篇)
    选择率和硬解析 我们上面提到了,在v$sql_cs_histogram视图中,如果此游标的3个桶中出现了两个桶中的count都有非0值,那么此后的解析都要窥探绑定变量的值计算谓词选择率,如果计算选...
    99+
    2024-04-02
  • Adaptive Cursor Sharing分析
    这篇文章主要讲解了“Adaptive Cursor Sharing分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Adaptive Cursor Shar...
    99+
    2024-04-02
  • 11gR2 新特性之(一)Adaptive Cursor Sharing(ACS)
    11gR2 新特性之(一)Adaptive Cursor Sharing(ACS) http://www.killdb.com/2011/06/19/11gr2-%e6%96%b0%e7%89%b9%e6%...
    99+
    2024-04-02
  • 如何进行 Adaptive Cursor Sharing的研究
    如何进行 Adaptive Cursor Sharing的研究,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。    Adaptiv...
    99+
    2023-06-06
  • 第二篇:ssh.invoke_shell
    接上一篇:按照上一篇的方式,在没有对ssh.invoke_shell()执行后的登录提示符进行判断的话,那边有部分机器就回因为返回为空导致程序卡死。 正常机器  ssh.recv(9999)  命令返回内容: b'Last login: ...
    99+
    2023-01-30
    第二篇 ssh invoke_shell
  • SQL Profile(第二篇)
    通过SQL Tuning Advisor使用SQL profile 在11GR2上SQL Tuning Advisor已经变得非常好用,我非常喜欢将一些非常复杂的SQL语句交给SQL Tunin...
    99+
    2024-04-02
  • robotFramework第二篇之关键
    lesson.robot 1 *** Keywords *** 2 打开谷歌浏览器并访问百度首页 3 Log 打开浏览器,输入http://www.baidu.com,进入百度首页 4 5 输入用户名 6 ...
    99+
    2023-01-30
    第二篇 关键 robotFramework
  • 【Python之旅】第四篇(二):Pyt
        在Python程序的执行过程中,难免会出现异常的情况,如果做的是跟用户交互的程序,当用户输入不可接受的内容时,在可预见的范围内,我们当然是希望可以给用户一些提示,而不是原来Python内置异常中的那些提示语句,毕竟那些语句只适合给程...
    99+
    2023-01-31
    之旅 第四篇 Python
  • 【Python之旅】第二篇(一):Pyt
    说明:    主要是file()和open()函数的使用,但在查open()函数的帮助时,会有下面的说明:>>> help(open) …… Open a file using the file() type, retur...
    99+
    2023-01-31
    之旅 第二篇 Python
  • 【Python之旅】第五篇(二):Pyt
        前面第五篇(一)中的一个Socket例子其实就是单线程的,即Server端一次只能接受来自一个Client端的连接,为了更好的说明socket单线程和阻塞模式,下面对前面的例子做修改。1.单线程+阻塞+交互式    前面的例子是单线...
    99+
    2023-01-31
    之旅 第五篇 Python
  • Python 学习日记第二篇 -- 列表
    一、列表    列表是一个可以包含所有数据类型的对象的位置有序集合,它是可以改变的。   1、列表的序列操作(Python3)>>> one_list = [1,2,3,4] >>> two_list =...
    99+
    2023-01-31
    第二篇 日记 列表
  • Java面试题冲刺第二天--Redis篇
    目录面试题1:为什么要用 Redis ?业务在哪块儿用到的?正经回答:深入追问: 追问1:Redis里有哪些数据类型?追问2:Redis与Memcached有哪些区别?追问3:那Re...
    99+
    2024-04-02
  • Python成长之路第二篇(3)_字典的
    字典的置函数用法(字典dict字典中的key不可以重复)class dict(object):"""dict() -> new empty dictionarydict(mapping) -> new dictionary in...
    99+
    2023-01-31
    字典 第二篇 成长之路
  • 第十二篇 1+X考证 Web前端测试题PHP篇(新)
     单选题  1、以下关于PHP面向对象的说法错误的是( A ) A、PHP可以多重继承,一个类可以继承多个父类 B、PHP使用new运算符来获取一个实例对象 C、一个类可以在声明中用extends关键字继承另一个类的方法和属性 D、...
    99+
    2023-09-06
    php 开发语言 前端
  • Java基础第二篇方法与数据成员
    目录1、调用同一对象的数据成员2、方法的参数列表3、调用同一对象的其他方法4、数据成员初始化5、总结上一篇文章Java基础 从HelloWorld到面向对象 1、调用同一对象的数据成...
    99+
    2024-04-02
  • 二:原神本地服务器(sifu)搭建环境配置教程第二篇
    安装jdk 双击msi安装文件,一路到底就欧克,傻瓜式安装。  安装数据库 也是一路yes,后面在安装界面会有一个询问你是否安装最新版,可选可不选,不选安装会快些 中间提示服务启动不成功也无所谓,可以忽略。后面会教你怎么开  安装代理器...
    99+
    2023-09-08
    windows 服务器
  • Android实战教程第二篇之简单实现两种进度条效果
    本文实例实现点击按钮模拟进度条下载进度,“下载”完成进度条消失,供大家参考,具体内容如下 代码如下: xml: <?xml version="1.0" e...
    99+
    2022-06-06
    进度条 教程 Android
  • 【MySQL从删库到跑路 | 基础第二篇】——谈谈SQL中的DML语句
    个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【MySQL学习专栏】🎈 本专栏旨在分享学习...
    99+
    2023-09-16
    mysql sql 数据库
  • springCloud分布式微服务云架构 第十二篇: 断路器聚合监控
    上一篇文章讲述了如何利用Hystrix Dashboard去监控断路器的Hystrix command。当我们有很多个服务的时候,这就需要聚合所以服务的Hystrix Dashboard的数据了。这就需要用到Spring Cloud的另一个...
    99+
    2023-06-05
  • 从零开始搭建Java开发环境第二篇:如何在windows10里安装MySQL
    1 下载安装包 1.1 压缩包 https://dev.mysql.com/downloads/mysql/ [外链图片转存失败(img-oesO8K09-1566652568838)(data:image...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作