Oracle 优化统计数据之直方图(histograms)(四)

2014-11-24 17:27:03 · 作者: · 浏览: 1
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 7 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 7 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | SKEW_IDX | 1 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------


2 - access("SKEW"=1)


14 rows selected.


现在优化器对于谓词skew=10000选择了全表扫描且能精确计算出它的基数9990.注意现在skew列的density是变成了0.00005也就是1/(2*num_rows)或者0.5/num_rows.


高度平衡直方图(height-balanced histograms)
在频率直方图中oracle给每一个不同值分配一个桶,然而桶的最大个数是254,因此如果表中的列有大量的不同值(超过254),将会创建一个高度平衡的直方图.


在高度平衡直方图中,因为我们的不同值超过了桶的个数,因此oracle首先分对列数据进行排序然后将数据集按桶数进行分类且除了最后一桶可能包含的数据比其它的桶少以外,所有其它的桶包含相同数量的值(这就是为什么叫高度平等直方图的原因).


这是有一个单独的语句用来创建高度平衡直方图.当请求的桶数少于列中不同值的个数时,oracle就会创建一个高度平衡直方图且这意味着endpoint_value和endpoint_number是不相同的.为了解释这种类型直方图的信息先看一个列有23个值且有9个不同值的例子.假设我们指定直方图的桶数是5,下面的图表显示了这些数据是如何存储在直方图中的:


Oracle 优化统计数据之直方图(histograms)


基于上面的图表可以得出以下信息:
直方图的桶数比列中的不同值的个数小
因为我们指定了直方图的桶数是5,所以整个数据集除了最后一个桶(在这里只有3个值)其它按相同的大小分配到每一个桶中.
每一个桶中的endpoints和第一个桶中的first point被标记因为它们有特殊意义.
数据3被标记为红色,它是一种特殊情况它的endpoint出现在多个桶中.


下面的图表是直方图的另一种显示方式:


Oracle 优化统计数据之直方图(histograms)


使用5个桶且列有23个值这意味着除了最后一个桶只有3个值以外其它每一个桶都有5个值.实际上这是oracle在数据字典视图中存储高度平衡直方图信息的方式.因为bucket 1和2都使用3作为一个endpoint,oracle为了节省空间将不会存储bucket 1.所以当桶被合并时只会存储单个条目.


Oracle 优化统计数据之直方图(histograms)


下面我们来对列skew创建一个高度平衡直方图,这一次让桶数小于列的不同值的个数11: SQL> select column_name,endpoint_number,endpoint_value from
2 user_tab_histograms where table_name='T1' and column_name='SKEW';


COLUMN_NAME ENDPOINT_NUMBER ENDPOINT_VALUE
--------------- -------------- --------------
SKEW 0 1
SKEW 5 10000

这里buckets 1到5都是用10000作为它的endpoint所以bucket 1到4为了节省空间没有被存储.下面的查询能用来显示桶数和它的endpoinit值
SQL> SELECT bucket_number, max(skew) AS endpoint_value
2 FROM (
3 SELECT skew, ntile(5) OVER (ORDER BY skew) AS bucket_number
4 FROM t1)
5 GROUP BY bucket_number
6 ORDER BY bucket_number;


BUCKET_NUMBER ENDPOINT_VALUE
------------- --------------
1 10000
2 10000
3 10000
4 10000
5 10000

这里ntile(5)是一个分析函数,它将一个有序的数据集划分到5个桶中.


所以简而言之,在高度平衡直方图中,数据被划分到不同的桶中除了最后一个桶每一个桶包含相同的数据.每一个桶中的最大值被记录为endpoint_value而第一个桶中的最小值也被记录(bucket 0).endpoint_number代表桶数.一旦数据被记录到桶中将会识别为2种类型的数据:
Non popular values和popular values.


Popular values是哪些作为endpoint value出现多次的值.例如在前面的例子中3是一个popular值,在上面的例子中skew 10000是一个popular value.non popular value是哪些没有作为endpoint values出现或者只作为endpoint values出现一次的值.popular value和non popular value不是固定的它依赖于直方图桶的大小,改变桶的大小会出现不同的popular值.

小结:
列中不同值的个数小于直方图的桶数:当不同值的个数小于桶数时,endpoint_value列包含的是不同值本身,endpoint_number列包含是小于列值的累积行数.(频率直方图)

列中不同值的个数大于直方图的桶数:当不同值的个数大于桶数时,endpoint_number包含的 bucekt id且endpoint_value是显示的每一个桶中的最大值.bucket 0是一个特殊它显示的是列中的最小值(高度平衡直方图).