分类: Oracle
2009-08-28 11:19:30
Oracle执行io是通过以块为单位的。因此,优化器决定使用全表扫描还是索引扫描,取决于所访问的block数,而不是记录行。这就称作index clustering factor。如果块中只包含一条记录,此时记录访问和块访问的成本是相同的。然而,大部分表拥有很多块,而每一块又拥有很多条记录。因此,这些理想的记录可以clustered在很少的块上,或者分布在很多块上。
虽然clustering factor是index的一个特性,但是clustering factor却实际上也与表中索引列的数据块分布相关。一个较低的clustering factor表明表中单独的记录行聚集在很少的数据块上。相反,较高的clustering factor指示着表中单独的记录随机分布在很多数据块上。因此,较高clustering factor意味着需要更多的成本来执行index range scan,因为需要读取更多的block才能得到结果。
下面的例子可以很少地说明这一点:
假定有以下环境,某个表中有9条记录,其上有一个非唯一索引 col1(tab1),这个c1列上实际存储A,B,C三个值之一。该表有三个oracle block。
l 情况一、索引clustering factor非常小,则数据块可能以以下模式存放:
Block 1 Block 2 Block 3
------- ------- --------
A A A B B B C C C
这是因为索引列值相同的存储在相同的物理块上。如果查询返回索引列值为A的记录,则只需要读取一个块。
l 情况二、如果表重组,以致索引值scattered across the table blocks,这时index clustering factor 非常高。
Block 1 Block 2 Block 3
------- ------- --------
A B C A B C A B C
如果查询返回索引列值为A的记录,则需要读取三个块。
Clustering factor是一种测量相对于基表上的索引的顺序程度。它一般用来评估在表上执行index访问所耗费的成本。它记录着执行索引扫描时需要访问的数据块。
Clustering factor可以从以下视图中查看:
l All|dba|user_indexes
l All|dba|user_ind_partitions
l All|dba|user_ind_subpartitions
它的值是按照以下算法计算出来的:
l 索引按顺序扫描
l 将当前扫描的索引条目的rowid与前一个扫描的rowid做比较,这个比较是在索引的leaf block完成(这些块本身无需访问)。
l 如果发现这两个相邻索引条目的rowid指向不同的block,这时计算器自动计数(自增)。
l 这个动作贯穿于整个index。
l 这个计数结果被存储下来。
如果这个计数值与表中的block数比较接近,则说明索引是有良好的排序。这是因为只有发现相邻索引条目的rowid指向不同的数据块时,才会计数。
如果这个计数值与表中的记录数比较接近,则说明索引是无序的。在这种情况下,相邻的索引条目可能指向不同的数据块,查找某个索引值的时候可能需要读取更多的数据块。
这个clustering factor可以用来调整某个特殊查询所需要访问的block数目。这个决定了使用索引访问表时可能需要访问表的block数目。
当使用索引查找结果时,clustering factor是一个高效的计数器,用来确定需要访问的数据块的数目。将此值乘以索引的选择性将会得出本次操作的成本。index range scan的成本由其控制。