Oracle 索引介绍
群:127881306
索引是建立在表的一列或多个列上的辅助对象,目的是加快访问表中的数据(加快查询);
索引由根节点、分支节点和叶子节点组成,上级索引块包含下级索引块的索引数据,叶节点包含索引数据和确定行实际位置的rowid。
查询DBA_INDEXES视图可得到表中所有索引的列表,注意只能通过USER_INDEXES的方法来检索模式(schema)的索引。访问USER_IND_COLUMNS视图可得到一个给定表中被索引的特定列。
通过每个行的ROWID,索引Oracle提供了访问单行数据的能力。ROWID其实就是直接指向单独行的线路图.
索引分类:
? 逻辑上:
单列索引, 多列索引, 唯一索引,非惟一索引。
? 物理上:
B*-Tree索引,反向索引,位图索引。
单列索引和复合索引
? 单列索引是基于单个列所建立的索引。多列索引是基于两列或多列所建立的索引。
? 单列索引
Create index emp_ind1 on emp(ename);
? 复合索引
Create index emp_ind2 on emp(ename,job);
惟一索引和非惟一索引
? 惟一索引是索引列值不能重复的索引。
? 非惟一索引是索引列值可以重复的索引。无论是惟一索引还是非惟一索引,索引列都允许NULL。
? B*-tree索引
? B*Tree索引是最常见的索引结构,默认建立的索引就是这种类型的索引。B*Tree索引在检索高基数数据列(高基数数据列是指该列有很多不同的值)时提供了最好的性能。当取出的行数占总行数比例较小时B-Tree索引比全表检索提供了更有效的方法。但当检查的范围超过表的10%时就不能提高取回数据的性能。B-Tree索引是基于二叉树的,由分支块(branch block)和叶块(leaf block)组成。在树结构中,位于最底层底块被称为叶块,包含每个被索引列的值和行所对应的rowid。在叶节点的上面是分支块,用来导航结构,包含了索引列(关键字)范围和另一索引块的地址 .
? 创建索引:
1: create index STUDENT_IND_name on STUDENT(NAME) tablespace USERS ;
2:create index STUDENT_IND_name on STUDENT(NAME,AGE) tablespace USERS ;
? 假设我们要找索引中值为80的行,从索引树的最上层入口开始,定位到大于等于50,然后往左找,找到第2个分支块,定位为75-100,最后再定位到叶块上,找到80所对应的rowid,然后根据rowid去读取数据块获取数据。如果查询条件是范围选择的,比如where column >20 and column <80,那么会先定位到第一个包含20的叶块,然后横向查找其他的叶块,直到找到包含80的块为止,不用每次都从入口进去再重新定位。
? 反向索引
? 反向索引是B*Tree索引的一个分支,它的设计是为了运用在某些特定的环境下的。Oracle推出它的主要目的就是为了降低在并行服务器(Oracle Parallel Server)环境下索引叶块的争用。当B*Tree索引中有一列是由递增的序列号产生的话,那么这些索引信息基本上分布在同一个叶块,当用户修改或访问相似的列时,索引块很容易产生争用。反向索引中的索引码将会被分布到各个索引块中,减少了争用。反向索引反转了索引码中每列的字节。
? 建立反向索引:
create index reversed_ind_emp on emp(Order_ID) reverse;
如果有一个名称为order_id的列值在某行上是12345,oracle就将它颠倒为54321。这样连续的几个数不会在同一个页块里。不过反向索引又一个缺点就是不能在所有使用常规索引的地方使用。在范围搜索中其不能被使用,例如,where column>value,因为在索引的叶块中索引码没有分类,所以不能通过搜索相邻叶块完成区域扫描。
注意:只有索引中的值是逆向的,表中的值保持不变
位图索引
? 位图索引主要用于决策支持系统或静态数据,不支持行级锁定。位图索引最好用于低cardinality列(即列的唯一值除以行数为一个很小的值,接近零),例如又一个“性别”列,列值有“Male”,“Female”,“Null”等3种,但一共有300万条记录,那么3/3000000约等于0,这种情况下最适合用位图索引。
? 创建位图索引:
create bitmap index inx_bitmap_emp on emp(sex);
位图索引的格式
行值? 1?2?3?4?5?6?7?8?9?10
Male? 1?0?0?0?0?0?0?0?1?1
Female?0?1?1?1?0?0?1?1?0?0
Null? 0?0?0?0?1?1?0?0?0?0
如果搜索where?gender=’Male’,要统计性别是”Male”的列行数的话,Oracle很快就能从位图中找到共3行即第1,9,10行是符合条件的;如果要搜索where?gender=’Male’?or?gender=’Female’的列的行数的话,也很容易从位图中找到共8行即1,2,3,4,7,8,9,10行是符合条件的。如果要搜索表的值的话,那么Oracle会用内部的转换函数将位图中的相关信息转换成rowid来访问数据块。