下面测试一下这句话的真实性:
hr@ORCL> create table t (id number,name varchar2(10));
㈡ INDEX FULL SCAN和 INDEX FAST FULL SCAN
在一句SQL中,如果我们想搜索的列都包含在索引里面的话
那么Index Full Scan 和 Index Fast Full Scan 都可以被采用代替Full Table Scan
有索引排序的时候,优化器可能会偏向于Index Full Scan
如果Select 列表中数据都可来自于索引中包含的字段,则通常容易选择Index Fast Full Scan
这样出来的数据是根据索引 的 extent 为单元,无顺序的
扫描block包含了所有枝节点,不区分是否叶子节点。可以做多块顺序扫描,一个io 包含多个block
Index Full Scan 是根据索引的叶子节点顺序获取叶子节点信息然后获得数据(通常还去表中获取数据)
这样出来的数据是有序的,并且除了定位第一个叶子节点走了根和枝节点block外
其他叶子节点只由上一个叶子节点的next 指针获得,这样一个索引叶子block就可产生一个io,是离散读
10g在Index Full Scan阶段就把不符合记录的数据先给过滤掉了,最后只有符合条件的rowid做回表
而9i下,Oracle就比较傻了,Index Full Scan的阶段实际上什么也没做
只是把所有的rowid都给得到,然后根据得到的rowid从表中取出数据,再过滤掉不符合条件的记录
INDEX_FFS使用多块读,所以在大部分时候,INDEX_FFS速度应该会比单块读的INDEX_FS要快
Index Full Scan将会按逻辑的顺序访问各个索引节点,结果集已经按照索引键值顺序排序,不需要单独排序
Index Fast Full Scan时索引块通过多块进行读取,结果集是无序的
所以,如果结果集需要排序那会使用INDEX_FS,如果结果集不需要排序则会使用INDEX_FFS
INDEX FULL SCAN
HINT写法:INDEX(表名 索引名)或者 INDEX_FS(表名 索引名)
原理:Oracle定位到索引的ROOT BLOCK,然后到BRANCH BLOCK(如果有的话),再定位到第一个LEAF BLOCK
然后根据LEAF BLOCK的双向链表顺序读取。它所读取的块都是有顺序的,也是经过排序的
INDEX FAST FULL SCAN
HINT写法:INDEX_FFS(表名 索引名)
原理:从段头开始,读取包含位图块,ROOT BLOCK,所有的BRANCH BLOCK,LEAF BLOCK
读取的顺序完全有物理存储位置决定,并采取多块读,每次读取DB_FILE_MULTIBLOCK_READ_COUNT个块
IFFS的成本计算公式是:
leaf_blocks/k (k依赖于db_file_multiblock_read_count,leaf_blocks依赖于索引统计信息)
查询某个表记录总数的时候,往往基于PRIMARY KEY的INDEX FAST FULL SCAN是最有效的
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/23490154/viewspace-1423761/ ,如需转载,请注明出处,否则将追究法律责任。