您的位置:首页 > 数据库 > Oracle

oracle索引方式详解

2015-07-22 10:36 656 查看
从物理操作上看,Oracle会采用以下两种方式来进行读取:

       单块读取数据:读取单位为Oracle数据库块。即便我们仅需要一行数据,Oracle也会将数据行所在数据块的数据完整地读入数据缓存。

       连续读取数据:读取单位有Oracle参数db_file_multiblock_read_count决定(也取决于操作系统一次IO的最大值),该参数的默认设置为16.

       那么如何获得需要读取那些数据块呢?

        这就需要从Oracle执行数据扫描的路径来看。从逻辑角度讲,数据扫描会有两种可能——基于表的全表路径扫描和基于索引的索引路径扫描。

       1、全表扫描(FTS,Full Table Scans)

       2、索引路径扫描
       索引不仅包含被索引的字段值,还包含行的位置标识Rowid,如果语句只检索索引字段,Oracle将直接从索引中读取而不需要通过Rowid去访问表,如果语句通过索引检索其他字段值,则Oracle通过索引获得Rowid从而迅速找到具体的行。

       索引扫描类型:

       1) 唯一索引扫描(Index Unique Scans) ;扫描唯一索引或主键,要么返回一行数据要么返回0行数据

       2) 索引范围扫描(Index Range Scans) ;访问选择性数据最常用的扫描方式;按顺序的对某个索引进行扫描,返回数据是升序排列的,可以使用唯一索引和非唯一索引;如果对索引列使用ORDER BY/GROUP BY则可省略排序,对索引进行范围扫描来获得索引字段的最大或最小值

       3) 索引降序范围扫描(Index Range Scans Descending) ;以索引逻辑顺序相反的顺序进行范围扫描

       4) 跳跃式索引扫描(Index Skip Scans) ;其实质是将索引分解成多个小的子索引来提高效率

       5) 全索引扫描(Full Index Scans) ;逐一读取索引中的所有块,由于索引中数据已按索引键排序,因此会忽略掉排序,它每次只能读取一个数据块

       6) 快速全索引扫描(Fast Full Index Scans) ;只扫描索引中的数据,不会扫描表中的数据;由于索引中数据未按索引键排序,因此不能忽略掉排序

       7) 索引连接(Index Joins)

 

       访问路径就是从数据库里检索数据的方式。优化器首先检查WHERE子句和FROM子句的条件,确定有哪些访问路径是可用的。然后优化器使用这些访问路径或各访问路径的联合,产生一组可能存在的执行计划,再通过索引、字段、表的统计信息评估每个计划的成本,最后优化器选择成本最低的执行计划所对应的访问路径。

       如果SQL语句的FROM子句无SAMPLE或SAMPLE BLOCK,优化器在选择访问路径的时候会优先考虑语句中的HINTS。

       在解释上述索引扫描类型之前,首先要明确一个问题——Oracle对I/O的评估是针对“块”的而不是“行”。优化器在决定是使用全表扫描还是索引扫描时,看的是所涉及块占全表的比例而不是检索的行占表的比例。当然如果一个块中只包含一个行数据,那么访问块和行是等同的,但是通常情况下都是一个块中含有多个行的数据,因此如果检索的行都聚集在少数块中则会大大降低I/O。

        几种索引扫描方式的比较:

        索引唯一性扫描(INDEX UNIQUE SCAN)(针对unique index的扫描)比索引范围扫描(INDEX UNIQUE SCAN)需要的逻辑读至少少1,这是因为索引唯一行扫描明确只有最多一行数据返回,而索引范围扫描则可能有多行数据返回,得到第一行数据之后还会向下至少再扫一个叶子节点。

        索引全扫描(INDEX FULL SCAN):索引全扫描不需要扫描该索引的所有分支块,Oracle在做索引全扫描的时候只需要访问必要的分支块的定位到位于该索引最左边的叶子块的第一行索引行,通过叶子块之间的双向指针链表就可以互相访问了。因为是按照从左至右进行扫描的,所以索引全扫描得到的数据是排好序的。索引全扫描一般都是不回表的,例如select count(*) from table; select empno from emp;能做索引全扫描的一个条件就是目标索引至少有一个索引键值列的属性是not
null。

        索引快速全扫描(INDEX FAST FULL SCAN):和索引全扫描差不多,一般也是不回表的,但也有很多区别。

        和索引全扫描的区别是:

        索引快速全扫描  只有在CBO中能用

        索引全扫描  不能并行执行,而索引快速全扫描既可以使用多块读也可以使用并行执行。

        索引快速全扫描  的结果并不一定是有序的。因为索引快速全扫描时Oracle是根据索引行在磁盘上的物理存储位置来扫描的,而不是根据索引行的逻辑顺序扫描的。

        索引跳跃式扫描(INDEX SKIP SCAN):适合所有类型的复合B树索引,(包括唯一性索引和非唯一性索引),它使得那些在where条件中没有针对目标索引的前导列指定查询条件同时又对该索引的非前导列制定了查询条件的目标SQL依然能够使用该索引。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: