数据库版本是10g收集直方图使用参数skewonly有缺陷,11g已经解决,实验如下:
SQL> create table test
2 (
3 id varchar2(60) primary key,
4 name varchar2(100)
5 );
表已创建。
SQL> insert into test
2 select rpad('a', 40, 'a') || to_char(rownum), object_name
3 from dba_objects;
已创建89139行。
SQL> commit;
提交完成。
SQL> exec dbms_stats.gather_table_stats(user,'test',METHOD_OPT=>'for all columns size skewonly');
PL/SQL 过程已成功完成。
SQL> select COLUMN_NAME, NUM_DISTINCT from user_tab_columns where TABLE_NAME = 'TEST';
COLUMN_NAME NUM_DISTINCT
------------------------------ ------------
ID 16
NAME 49489
SQL> exec dbms_stats.gather_table_stats(user,'TEST',METHOD_OPT=>'for all columns size auto');
PL/SQL 过程已成功完成。
SQL> select COLUMN_NAME, NUM_DISTINCT from user_tab_columns where TABLE_NAME = 'TEST';
COLUMN_NAME NUM_DISTINCT
------------------------------ ------------
ID 89139
NAME 49489
原因是在size skewonly的模式下,Oracle是根据id前32个字节来判断的,并没有对整个varchar2(60)字段进行分析,有兴趣可以用10046跟踪看一下。