直方图统计数据的研究
对oracle 10G 10.2.0.4 直方图的研究
在调用dbms_stat生成统计信息时(sql见下),
SQL> SET SERVEROUTPUT ON
SQL> BEGIN
2 DBMS_OUTPUT.ENABLE(1000000);
3 dbms_stats.set_param('TRACE', 16383); --在dbms_stats.gather_table_stats执行中产生全部trace信息
4 dbms_stats.gather_table_stats( --由oracle自动决定采样范围 是否创建直方图
5 ownname => user,
6 tabname => 'T'
7 );
8 END;
9 /
会检查col_usage$中对列的使用,包括where中是否含有等式、范围(betwwen)、连接等,
oracle会先尝试创建频度直方图,如创建失败(如唯一值数大于254),再尝试创建等高直方图,对于char类型的列
,如果有where中包括范围判断,一般会成功创建等高直方图,如果没有范围条件,一般会提示忽略等高直方图:
Discarding Histogram (not necessary)
如果where中包括范围判断条件,还要对该列的值的分布进行检查,判断是否有倾斜,倾斜的意思
实际上就是每个桶的最大值是否平均的增加,即平均的从1号桶的最大值增加到最后一个桶的最大值,
如果有多个连续的桶的最大值都不是平均增加的,则意味该列的值是倾斜的。
判断逻辑如下:
先取出该列所有行的最大、最小值,然后计算平均桶值差diff=(MAXVAL - MINVAL) /桶数
桶数一般要算上0号桶,比如如果dbms_stat时,桶参数为10,则桶数就是11;
生成一个桶边界值 THRESHOLD := 最小值 + 平均桶值差DIF;
随后while循环1处理每个桶:
再while循环2判断 当前桶最大值是否 大于 桶边界初始值
如当前桶最大值 大于 桶边界初始值
桶倾斜度累计量增加;累加值为 当前桶编号与上次未满足循环2条件的桶编号差值的平方
平方的意思是指数增加,体现倾斜度的影响是指数上升的
累计完一次后 “当前桶编号与上次未满足循环2条件的桶编号差值”清零
桶边界值增加一个diff:THRESHOLD := THRESHOLD + DIF;
while循环2判断条件不满足
桶编号差值累计增加:下一个桶编号与当前桶编号之差(一般情况下是1)
while循环1处理完所有的桶;
判断 桶倾斜度累计量/桶数 是否大于1.7
是 则返回有倾斜
不是 则返回无倾斜