全部博文(389)
分类: Oracle
2013-12-10 22:41:07
ORACLE高度平衡直方图谓词评估
在之前的一篇文章中提到,oracle对于栏位distinct值大于手动指定的值或
distinct value大于254就会构建高度平衡直方图( HEIGHT BALANCED)
以用户frank创建表T2,值的分布如下.
SQL> select a,count(*) from frank.t2 group by a order by a;
A COUNT(*)
---------- ----------
1 100
2 100
3 1
10 200
11 200
15 200
16 300
构造数据分布不均匀,再在该栏上创建直方图,桶数为5,这样bucket的数量就小于栏位A的distinct value 7
SQL> begin
2 dbms_stats.gather_table_stats(tabname=>'T2',ownname=>'FRANK',method_opt=>'FOR COLUMNS A SIZE 5');
3 end;
4 /
PL/SQL procedure successfully completed.
SQL> select * from user_histograms where table_name='T2' and column_name='A';
TABLE_NAME COLUMN_NAM ENDPOINT_NUMBER ENDPOINT_VALUE ENDPOINT_A
---------- ---------- --------------- -------------- ----------
T2 A 0 1
T2 A 1 10
T2 A 2 11
T2 A 3 15
T2 A 5 16
通过max endpoint_number可以看出oracle创建了5个bucket.经过压缩过后桶的数量为4,第0个不算
现在来看histogram对cardinality的评估.
SQL> explain plan for select * from t2 where a=3;
Explained.
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 110 | 660 | 3 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T2 | 110 | 660 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------
对a=3的评估为110,a的实际行数为1.根据高度平衡的算法,从中我们可以总结出高度平衡直方图对于"="谓词的评估算法.
高度平衡直方图的特点就是每个桶中的行数是一样的.1101/5个可以算出每个bucket包括的行数是220.2.
公式为:
如果谓词等于endpoint_value
(num_rows)/(max endpoint_number)*(endpoint_number-endpoint_number(上一个)-trunc((1/trunc(distinct value)/(buckets-1))),111))
如果谓词不等于endpoint_value
(num_rows)/(max endpoint_number)*trunc((1/trunc(distinct value)/(buckets-1))),1111)
通过以上的公式,我们可以算出值例子中的cardinlity.3小于10,落在endpoint_number 为1的桶中
(1101)/5*trunc((1/trunc(7/(4-1))),111)=110.1
高度平衡直方图本身的算法决定每个桶中存放相同数据的行(num_rows)/(max endpoint_number),可以算出每个桶中存
放的行数为220行,在压缩过后桶的数量为4的结果出来后,oracle会假设值在桶里平均分布,最后一个桶中放最后的值.所以4个桶,
前3个桶每个桶中存放2个值.最后1个桶中存放的是最后1个值,那么每个桶中每个值出现的机会就是 1/2.
而endpoint_number-endpoint_number(上一个)是因为有时候会存在压缩.从这里也可以看出高度平衡直方图并不是很准确.
再来看看16,endpoint_number 5的endpoint_value为16,通过我们的可式可以算出
(1101)/5*((5-3)-trunc((1/trunc(7/(4-1))),111))=330.3
SQL> explain plan for select * from t2 where a=16;
Explained.
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 330 | 1980 | 3 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T2 | 330 | 1980 | 3 (0)| 00:00:01 |
对于>,<,>=,<=的谓词,我们可以根据返回的行数可以总结出来.对于endpoint_value落在最后一个桶中的value,值的评估是0.5.需要注意