2.3.3 索引聚簇因子

再次回到上一节抛出的问题,什么时候应该用索引?前面我们分析过了索引选择度和数据分布的问题,而另一个会影响索引使用的关键因素就是索引聚簇因子(INDEX CLUSTERING FACTOR)。

什么是索引聚簇因子呢?索引聚簇因子是指按照索引列值进行了排序的索引条目顺序和其对应表中数据行顺序的相似程度。比较理想的状况就好比一对双胞胎,其相似程度是非常大的,此时索引使用是非常高效的。在Oracle中,聚簇因子大小对数据读取效率有着直接的影响,聚簇因子值越小,则说明相似程度越大,索引使用将越趋于高效。

聚簇因子是如何影响索引的使用性能的呢?主要从I/O开销这个角度来思考。如图2-9所示,我们先来对比一下左右两种情况的聚簇因子。我们假设一个表中只有三个数据块(Data Block),每个数据块只能存储三行数据,共需存储9行记录。现有一个索引列,9行记录对应索引列值为123123123,在索引结构中对键值是有序排列的,那索引条目存储的顺序应该为111222333。右图中,表中数据存储的顺序也是111222333,和索引顺序是一致的;左图中表和索引存储的结构则是大相径庭的。按照聚簇因子的定义,左图可以视为较差(或者较大)的聚簇因子,右图可以视为较好(或者较小)的聚簇因子。

 book_ch02_09

图2-9  索引聚簇因子I/O影响

当进行索引扫描的时候,其实左右图并无什么区别,因为索引都是有序的,但是在回表取数的时候,右图的I/O开销较明显小于左图的。现在假设每次I/O只能读取一个数据块,那么当查询COL=1的时候,右图只需一次I/O,左图需要三次,I/O上的优势立现。优化器在COST计算的时候,对于左图的情况甚至会选择全表扫描,而放弃走索引。

为什么会造成表存储结构和索引存储结构不一致呢?索引结构的存储因为是有序排序了,所以不一致的问题出在表的存储上。我们通常所说的表都是堆表,其最大特征就是数据存储的独立性,数据的存储和数值本身没有任何关系,是随机存储在任意位置上,即随机存储在任意的数据块上。

很幸运的是,Oracle提供了索引的聚簇因子,可以通过数据字典查询到相关索引的聚簇因子信息,如下:

SQL> select index_name, clustering_factor
2  from dba_indexes where table_name='ALEX_T03';

INDEX_NAME                         CLUSTERING_FACTOR
------------------------------ -----------------
PK_ALEX_T03                                         247
IDX_ALEX_T03_COL1                                  251

简单来说,CLUSTERING_FACTOR反映的是通过索引扫描访问一张表,需要访问的表的数据块数量,即反映I/O的次数。这个CLUSTERING_FACTOR是如何计算出来的呢?

(1)       扫描索引结构;

(2)       顺序对比相邻索引条目的ROWID,如果两个ROWID属于不同数据块,那么CLUSTERING_FACTOR增加1;

(3)       整个索引扫描结束后,就可以得到该索引的聚簇因子数值。

了解了CLUSTERING_FACTOR的计算方法,我们可以得出以下两个极端的情况,即聚簇因子最大和最小的情况:

q  CLUSTERING_FACTOR最小时,其无限接近于表的数据块数,该表是按照索引字段顺序存储的;

q  CLUSTERING_FACTOR最大时,其无限接近于表的行数,该表是完全不按照索引字段顺序存储的。

提示

结合聚簇因子和选择度,基本上就可以确定索引扫描的COST开销了。

Trackback

no comment untill now

Add your comment now

切换到手机版