size auto比size skewonly聪明的一个地方

  曾经我比较过dbms_stats.gather_table_stats里面method_opt参数的两个选项:size auto和size skewonly的区别,(详情请见 http://space.itpub.net/15415488/viewspace-591765)大致是讲size auto会多考虑column的使用情况来决定是否搜集柱状图,而size skewonly只需考虑这列是否倾斜即可。所以从这个层面上来看,如果我们确定希望搜集某个/些column(s)的柱状图时,size skewonly是更好的选择。但是,今天发现在某个特别的情况下,size auto能够识别一些size skewonly和size 都无法识别的一种情况。

  实验环境:10203 @ solaris 64 bit.

  建立一张实验用表:

create table testbyhao
(id varchar2(50) primary key,
name varchar2(100));

  插入的数据中的id这列,是由前缀40个'a'组成,后缀不一样的varchar2(50)组成。

insert into testbyhao
select rpad('a',40,'a')||to_char(rownum),
object_name from dba_objects;

  我先用size skewonly分析此表:

exec dbms_stats.gather_table_stats(user,'TESTBYHAO',METHOD_OPT=>'for all columns size skewonly');

  我们发现,分析后的id这列的distinct value为1,即Oracle并没有分辨出前缀前40个字符同样,但后缀不一样的varchar2(50)的数据。

SQL> select COLUMN_NAME,NUM_DISTINCT
  2  from user_tab_columns where TABLE_NAME='TESTBYHAO';

COLUM NUM_DISTINCT
----- ------------
ID               1
NAME          7899

  但我用size auto再分析此表:

exec dbms_stats.gather_table_stats(user,'TESTBYHAO',METHOD_OPT=>'for all columns size auto');

  我们发现,size auto模式成功识别出了所有id的不同来。

SQL> select COLUMN_NAME,NUM_DISTINCT
  2  from user_tab_columns where TABLE_NAME='TESTBYHAO';

COLUM NUM_DISTINCT
----- ------------
ID           11573
NAME          7899

   为了查明为什么,我做了10046 trace来比较两种分析的不同,对于size skewonly,我从trace文件里找到了这样一句SQL:

select substrb(dump(val,16,0,32),1,120) ep, cnt
from (select substrb("ID",1,32) val,count(*) cnt 
from "LONGRAW_USER"."TESTBYHAO" t 
where substrb("ID",1,32) is not null 
group by substrb("ID",1,32))
order by nlssort(val,'NLS_SORT = binary') ;
 

    原来在size skewonly的模式下,Oracle是根据id前32个字节来判断的,并没有对整个varchar2(50)字段进行分析。

    但是对size auto,我并没有在trace文件中找到相关的SQL。

另外,不仅仅是size skewonly,就连我手工指定size 254也都无法让Oracle变聪明:


SQL> exec dbms_stats.gather_table_stats(user,'TESTBYHAO',ESTIMATE_PERCENT=>100,METHOD_OPT=>'for all columns size 254');

PL/SQL procedure successfully completed.

SQL> select COLUMN_NAME,NUM_DISTINCT from
  2  user_tab_columns where TABLE_NAME='TESTBYHAO';

COLUM NUM_DISTINCT
----- ------------
ID               1
NAME          7899

所以,对于这种需要对前缀很长(超过32个字节)的varchar2字段计算distinct value时,需要使用聪明的size auto模式。

    出此之外,我们谈到了柱状图,那么在这种非常迷惑Oracle的情况下,到底会不会为ID这列搜集柱状图呢?

于是我依旧比较了size auto,size skewonly和size 254这三种情况:

SQL> exec dbms_stats.gather_table_stats(user,'TESTBYHAO',METHOD_OPT=>'for all columns size skewonly');

PL/SQL procedure successfully completed.

SQL> select HISTOGRAM from user_tab_columns
  2  where TABLE_NAME='TESTBYHAO' and COLUMN_NAME='ID';

HISTOGRAM
---------------------------------------------
NONE

SQL> exec dbms_stats.gather_table_stats(user,'TESTBYHAO',METHOD_OPT=>'for all columns size auto');

PL/SQL procedure successfully completed.

SQL> select HISTOGRAM from user_tab_columns
  2  where TABLE_NAME='TESTBYHAO' and COLUMN_NAME='ID';

HISTOGRAM
---------------------------------------------
NONE

SQL> exec dbms_stats.gather_table_stats(user,'TESTBYHAO',METHOD_OPT=>'for all columns size 254');

PL/SQL procedure successfully completed.

SQL> select HISTOGRAM from user_tab_columns
  2  where TABLE_NAME='TESTBYHAO' and COLUMN_NAME='ID';

HISTOGRAM
---------------------------------------------
FREQUENCY

    以上结果表明,果然只有size 才会搜集柱状图,size auto和size skewonly在搜集柱状图的选择上面的决定是一样的,这是因为size skewonly认为只有一行,自然不会搜集;size auto认为每行都不一样,也不会搜集。

 

    接着我到了11GR2环境看这样的情况是否能重现。

    实验环境:11GR2 @ Solaris 64 bit。

SQL> exec dbms_stats.gather_table_stats(user,'TESTBYHAO',METHOD_OPT=>'for all columns size skewonly');

PL/SQL procedure successfully completed.

SQL> select COLUMN_NAME,NUM_DISTINCT from user_tab_columns where TABLE_NAME='TESTBYHAO';

COLUMN_NAM NUM_DISTINCT
---------- ------------
ID                12943
NAME               9785


SQL> exec dbms_stats.gather_table_stats(user,'TESTBYHAO',METHOD_OPT=>'for all columns size auto');

PL/SQL procedure successfully completed.

SQL> select COLUMN_NAME,NUM_DISTINCT from user_tab_columns where TABLE_NAME='TESTBYHAO';

COLUMN_NAM NUM_DISTINCT
---------- ------------
ID                12943
NAME               9785

   现在,在11GR2时,size skewonly已经变聪明了:)

 

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

转载于:http://blog.itpub.net/15415488/viewspace-622255/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值