深入理解Oracle索引(10):索引列字符类型统计信

系统 1659 0

      ㈠ 先看两个来自生产环境的真实案例:

         

           案例1

           案例2

 

      ㈡ 原理:


     
     Oracle 在对于 varchar等字符型字段收集统计信息时,并不会对每个值都进行精确的统计
     而是,对值进行substr(,32)。一般来讲,这种方式没有什么问题
     但是,如果恰巧列中存储的数据,前32bytes相同,那么,Oracle 的统计就会与实际情况不符


     
      ㈢ 测试:

 

 

    hr@ORCL> drop table t purge;



Table dropped.



hr@ORCL> create table t (id number,name varchar2(300));



Table created.



hr@ORCL> create index idx_t on t (name);



Index created.



hr@ORCL> insert into t select rownum,lpad('a',6,'a')||to_char(rownum) from dba_objects;



50322 rows created.



hr@ORCL> commit;



Commit complete.



hr@ORCL> exec dbms_stats.gather_table_stats(user,'T',null,null,method_opt=>'for columns size 254 name',cascade=>true);



PL/SQL procedure successfully completed.



hr@ORCL> select column_name, endpoint_actual_value

  2        from user_tab_histograms

  3       where table_name = 'T'

  4             and rownum<5

  5        order by column_name, endpoint_Number;



COLUM ENDPOINT_ACTUAL_VALUE

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

NAME  aaaaaa46556

NAME  aaaaaa46734

NAME  aaaaaa46912

NAME  aaaaaa47090









hr@ORCL> truncate table t;



Table truncated.



hr@ORCL> insert into t select rownum,lpad('a',31,'a')||to_char(rownum) from dba_objects;



50322 rows created.



hr@ORCL> exec dbms_stats.gather_table_stats(user,'T',null,null,method_opt=>'for columns size 254 name',cascade=>true);



PL/SQL procedure successfully completed.



hr@ORCL> select column_name, endpoint_actual_value

  2        from user_tab_histograms

  3       where table_name = 'T'

  4             and rownum<5

  5        order by column_name, endpoint_Number;



COLUM ENDPOINT_ACTUAL_VALUE

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

NAME  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1

NAME  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2

NAME  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3

NAME  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4









hr@ORCL> truncate table t;



Table truncated.



hr@ORCL> insert into t select rownum,lpad('a',32,'a')||to_char(rownum) from dba_objects;



50322 rows created.



hr@ORCL> exec dbms_stats.gather_table_stats(user,'T',null,null,method_opt=>'for columns size 254 name',cascade=>true);



PL/SQL procedure successfully completed.



hr@ORCL> select column_name, endpoint_actual_value

  2        from user_tab_histograms

  3       where table_name = 'T'

  4             and rownum<5

  5        order by column_name, endpoint_Number;



COLUM ENDPOINT_ACTUAL_VALUE

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

ID

ID

NAME


  


 

      ㈣ 解决方案:


     
          删除索引列的直方图
          例子:

 

 

    SQL> begin

dbms_stats.gather_table_stats(ownname => 'HR',

                              tabname => 'T' ,

                              estimate_percent => null ,

                              method_opt => 'for columns SIZE 1 name' ,

                              cascade => true);

end;

/
  


 

 

深入理解Oracle索引(10):索引列字符类型统计信息的32位限制


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论