索引扫描

来源:互联网 发布:影响原油数据 编辑:程序博客网 时间:2024/05/18 03:07

转载自:http://blog.csdn.net/edwingu/article/details/6621554

索引行的存储顺序与表中行的存储顺序之间的相似程度被称为聚簇因子。聚簇因子会随着这种相似程度的不同而不同。

         当相类似行的密集程度比较高时,这些数据行就会被密集地存储在相对较少的数据块中,这是聚簇因子比较好的情况。相反,数据行被分散地存储在多个数据块中就是聚簇因子比较差的情况。在索引扫描中聚簇因子对数据的读取效率有着非常大的影响。

 

索引唯一扫描(Index Unique Scan)

         在大部分情况下该扫描方式主要被使用在检索唯一ROWID的查询中,为了进行索引唯一扫描而必须基于主键来创建索引,或者创建唯一索引,且在SQL语句中必须为索引列使用“=”比较运算符。否则即使基于具有唯一值的列创建了索引,在执行时优化器也不可能选择索引唯一扫描,而会选择范围扫描。

         在使用数据库链接(Database Link)时,尽管可以按照索引唯一扫描的方式执行,但是优化器有时却选择了其他扫描方式。此时如果使用提示进行引导,则可以达到预期目的。

 

索引范围扫描(Index Range Scan)

         该扫描是最普遍的数据读取方式,优化器选择该扫描方式的情况有两种,即有开始值与结束值的情况和有一个以上的行但没有结束值的情况。通过该扫描方式所检索出来的行的顺序与索引中的顺序相同,即使在查询语句中使用了ORDER BY,优化器也会根据具体情况进行判断。

         索引范围扫描虽然在寻找最初开始位置时使用的是随机读取,但之后所执行的全部都是连续扫描。如果再进行更准确扫描的话,即在查找分支块时使用的是随机读取,在经过分支块查找到开始的叶块之后所执行的都是连续扫描。

         索引块的数量不仅比表的数据块数量少,而且所读取的索引块都是互相连续的,所以读取索引块所需要的运输单价比较低。随着读取范围的变大而引起代价增大的主要原因其实并不是由索引引起的,而是由于在使用索引中的ROWID从表中读取相应的数据时代价增加得比较多的缘故。

 

索引降序范围扫描(Index Range Scans Descending)

         索引降序范围扫描除了是按照降序从表中读取数据之外,其他的部分都与索引范围扫描相同。一般情况下索引是按照升序对索引列值进行排序的,而该扫描方式则是从最大的值开始按照降序的方式连续扫描叶块,直至扫描到最小值为止。

         针对这种查询数据范围比较大的情况而言,如果按照降序进行扫描,则不仅省去了排序操作,而且还能够在很大程度上提高执行效率。

 

索引跳跃式扫描(Index Skip Scan)

         该方式是一种不遵循基本索引规则的重要扫描方式。我们知道如果构成索引的第一个索引列没有被赋予查询条件,则优化器将拒绝使用索引扫描,因此我们为了提高执行速度只能创建大量的索引。

         为解决组合索引中第一个索引列不再条件中而被优化器拒绝使用索引的问题,以及解决组合索引中间列没有在条件中而导致扫描数据量增加的问题,我们必须搜集大量的数据读取类型,并对这些类型所使用到的列进行综合分析,创建出最优的索引,以确保查询条件中所使用到的列最大限度地连续使用“=”运算符。

         当然,即使在索引跳跃式扫描能够被执行的条件下,也不能说上述这种复杂的综合分析、创建索引的方法是没有必要的。

         索引跳跃式扫描原理只有在最开始查找叶块时才扫描分支块,查找到开始叶块之后就连续对叶块进行扫描,直至结束。

         注意不要过于依赖索引跳跃式扫描,更不要因为过于相信索引跳跃式扫描的功能而随意创建第一个列不在查询条件中,或将不经常使用的列放到中间,或将使用非“=”比较运算符的列放到最前面的组合索引。

 

索引全扫描(Full Scan)

         在至少有一个索引列被赋予了查询条件的情况下,有可能使用索引全扫描,也就是说赋予查询条件的索引列并不一定是索引中的第一个列(以后将该列称为前导列)。在满足下面两个条件的情况下,即使没有为索引列赋予查询条件,该扫描方式也有可能被选择执行:

第一,   查询语句中所涉及的所有列都存在于索引中。

第二,   索引列中至少存在一个NOT NULL列。

例如,在执行”SELECT count(*) FROM table”时并不是从拥有大量数据块的表中读取数据,而是通过执行对某个索引的索引全扫描来存在结果,之所以这样执行是由于该查询语句满足上面所列举的两个条件。

 

索引快速全扫描(Fast Full Index Scan)

         在查询语句中所涉及的所有列都存在于索引中的情况下,索引快速全扫描有可能被选择执行,同样也应该满足索引列中至少存在一个NOT NULL列。

         在满足这两个条件的前提下,若该扫描方式一旦被选择执行,同样不需要从表中读取数据。索引快速扫描每次I/O读取的是多个数据块,这也是该方式与索引全扫描之间的主要区别。由于该扫描方式支持并行处理,所以索引快速全扫描与索引全扫描或者全表扫描相比速度更快,但该方式在位图索引中无法被使用。

         我们可以使用INDEX_FFS(table_alias index_name)提示来引导优化器选择索引快速全扫描。同样也可以使用NO_INDEX_FFS(table_alias index_name)提示来阻止。


0 0