ITPub博客

首页 > 数据库 > Oracle > 谓词越界

谓词越界

原创 Oracle 作者:bestpaydata 时间:2015-11-11 14:48:37 0 删除 编辑

    上一节中,根据公式算出基数的时候,对目标列指定的where查询条件都是在该列的最大值和最小值(统计信息里面的值)之间的。本节讨论,如果对该列的查询条件不在它们之间,即谓词越界的现象。
    下面例子:




点击(此处)折叠或打开

  1. select T.low_value,T.high_value,DUMP(T.high_value,16),dump(T.low_value,(16)),T.num_distinct,T.num_nulls from dba_tab_col_statistics T where table_name = 'T7' AND column_name = 'OBJECT_ID';




此时该列的最大值和最小值分别是(因为是raw类型的,需要用下面方法转换成10进制的方法)
SQL> var temp number
SQL> exec dbms_stats.convert_raw_value('C103',:temp);

PL/SQL procedure successfully completed.


      TEMP
----------
         2

SQL> exec dbms_stats.convert_raw_value('C3085F2F',:temp);

PL/SQL procedure successfully completed.


      TEMP
----------
     79446

可以看出此时,object_id的最大值和最小值为79446和2。
为了模拟本次实验,我用下面的存储过程插入几万条数据,并且不统计统计信息。


点击(此处)折叠或打开

  1. declare
  2.     i int;
  3. begin
  4.     for i in 80000 .. 90000 loop
  5.         insert into t7
  6.             (OWNER,
  7.              OBJECT_NAME,
  8.              SUBOBJECT_NAME,
  9.              OBJECT_ID,
  10.              DATA_OBJECT_ID,
  11.              OBJECT_TYPE,
  12.              CREATED,
  13.              LAST_DDL_TIME,
  14.              TIMESTAMP,
  15.              STATUS,
  16.              TEMPORARY,
  17.              GENERATED,
  18.              SECONDARY,
  19.              NAMESPACE,
  20.              EDITION_NAME)
  21.         values
  22.             ('SYS',
  23.              'ICOL$',
  24.              null,
  25.              i,
  26.              2,
  27.              'TABLE',
  28.              to_date('12-12-2014 02:51:05', 'dd-mm-yyyy hh24:mi:ss'),
  29.              to_date('12-12-2014 02:51:05', 'dd-mm-yyyy hh24:mi:ss'),
  30.              '2014-12-12:02:51:05',
  31.              'VALID',
  32.              'N',
  33.              'N',
  34.              'N',
  35.              1,
  36.              null);
  37.     end loop;

  38. end;
此时没有收集统计信息,所以列的统计信息的值依然是原来的值。
但此时表中列的最大值是 120000



此时我们再执行以下语句







因为没有收集统计信息,所以统计信息都没有变化。
上面的结果集是40000多条数据,cbo计算出的cardinality确为1,这里就是出现了“谓词越界”的现象,即如果对目标列指定的
where查询条件不在该列的最大值和最小值之间,cbo就无法判断出针对该列的查询条件的可选择率,所以只能用一个估算值来
作为针对该目标列的查询条件的可选择率。进而是cbo选错执行计划。

    可以针对上述,做一个10053的trace。


这里出现了谓词越界的现象,cbo用了一个很小的值0.000015来做为返回的基数。出现了严重的偏差。进而导致cbo选错了执行计划。

再次收集统计信息后,统计信息回归正常,如下:


此时再执行如上语句,变为了


效率更高。




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

请登录后发表评论 登录
全部评论

注册时间:2015-01-19

  • 博文量
    126
  • 访问量
    985796