ITPub博客

首页 > 数据库 > Oracle > 统计信息的32位限制

统计信息的32位限制

原创 Oracle 作者:sundog315 时间:2010-08-20 11:15:22 0 删除 编辑

原帖在此:http://www.itpub.net/thread-1339053-1-1.html

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

请看下面的例子:

[@more@]

SQL*Plus: Release 11.2.0.1.0 Production on 星期五 8月 20 10:40:54 2010

Copyright (c) 1982, 2010, Oracle. All rights reserved.

SQL> conn test/test
已连接。
SQL> drop table t;

表已删除。

SQL> create table t (id integer,name varchar2(300));

表已创建。

SQL> create index t_idx on t(name);

索引已创建。

SQL> insert into t
2 select rownum,lpad('a',6,'a')||to_char(rownum) from dba_objects;

已创建64972行。

SQL> commit;

提交完成。

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

PL/SQL 过程已成功完成。

SQL> select count(*)
2 from user_tab_histograms
3 where table_name = 'T'
4 order by column_name, endpoint_Number;

COUNT(*)
----------
255 --小于32字节,没问题

SQL> col column_name format a5
SQL> col endpoint_actual_value format a50
SQL> 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 aaaaaa57227
NAME aaaaaa57457
NAME aaaaaa57687
NAME aaaaaa57916


SQL> truncate table t;

表被截断。

SQL> insert into t
2 select rownum,lpad('a',32,'a')||to_char(rownum) from dba_objects;

已创建64972行。

SQL> commit;

提交完成。

SQL> exec dbms_stats.gather_table_stats(user,'T',null,null,method_opt=>'for colu
mns size 254 name',cascade=>true);

PL/SQL 过程已成功完成。

SQL> select column_name, endpoint_actual_value
2 from user_tab_histograms
3 where table_name = 'T'
4 order by column_name, endpoint_Number;

COLUM ENDPOINT_ACTUAL_VALUE
----- --------------------------------------------------
NAME

前32bytes相同,那么最后的桶只有1个

SQL> truncate table t;

表被截断。

SQL> insert into t
2 select rownum,lpad('a',31,'a')||to_char(rownum) from dba_objects;

已创建64972行。

SQL> exec dbms_stats.gather_table_stats(user,'T',null,null,method_opt=>'for colu
mns size 254 name',cascade=>true);

PL/SQL 过程已成功完成。

SQL> select column_name, endpoint_actual_value
2 from user_tab_histograms
3 where table_name = 'T'
4 order by column_name, endpoint_Number;

COLUM ENDPOINT_ACTUAL_VALUE
----- --------------------------------------------------
NAME aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1
NAME aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2
NAME aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3
NAME aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4
NAME aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa5
NAME aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6
NAME aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa7
NAME aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa8
NAME aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9

已选择9行。

完全符合32bytes。

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

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

注册时间:2010-01-05

  • 博文量
    126
  • 访问量
    540262