索引扫描
索引唯一扫描【Index unique scan】:
原理:从根节点到叶节点遍历整个树,直到查找到指定的条目,获取ROWID,然后根据ROWID查找到对应的数据行。
使用条件:WHERE条件中的列对应的是主键索引或唯一索引,而且该扫描方法只是用于单值扫描,也就是谓语为“=”。
hint:/*INDEX(table_alias index_name)*/
索引范围扫描【Index range scan】:
原理:查找开始值的时候采用的是遍历查找的方式,接着就是连续扫描leaf block直到查找完所有要求范围内的ROWID。
使用条件:需要返回一定范围数据,如>,<,>=,between,like,=等比较运算符。但是LIKE使用了‘%ABC’和通配符类型,不会使用索引范围扫描,因为条件太宽泛,以致于难以定位开始值。
注意:默认为升序,若扫描出来的数据行的顺序和索引顺序相同,则会忽略ORDER BY子句。
hint:/*INDEX(table_alias index_name)*/
索引降序范围扫描【Index range scans descending】:
原理:除了是按照降序从表中读取数据之外,其他的跟索引范围扫描一样。
注意:可以用其来避免ORDER BY的排序子句。
hint:/*INDEX_DESC(table_alias index_name)*/
索引跳跃式扫描【Index skip scan】:
原理:只有在最开始查找叶块时才扫描分支块,之后连续对分支块进行扫描,直到结束。原理跟索引范围扫描差不多。或者可以理解为逻辑上将多个列的索引分解为多个较小的索引来实现,也就是类似“引导列=** and predicate =** union all 引导列=** and predicate =** union all....”
使用条件:存在符合索引,但是WHERE中的谓语只是存在复合索引中的部分索引列,而没有引导列。
注意:引导列所决定的逻辑子索引数量越少,则索引跳跃式扫描的优势越明显,一致性读取(逻辑块读取)的数量越少
hint:/*INDEX_SS(table_alias index_name)*/,/*INDEX_SS_ASC(table_alias index_name)*/,
/*INDEX_SS_DESC(table_alias index_name)*/,/*NO_INDEX_SS*/
索引全扫描【Full scan】:
原理:扫描所有的leaf block,获取需要的条目,查找对应的数据行。
注意:可能会用其避免排序(min/max)(第一个数据块的第一个条目/最后一个数据块的最后一个条目)。
索引快速全扫描【Fast full index scan】:
原理:扫描所有的leaf block,直接读取其中的列值,而不再访问表数据块。
使用条件:查询列表中的所有字段都保存在索引中而且至少有一列具有非空约束时才可替代全表扫描。
hint:/*INDEX_FFS(table_alias index_name)*/,/*NO_INDEX_FFS(table_alias index_name)*/