索引在各种关系型数据库系统中都是举足轻重的组成部分,其对于提高检索数据的速度起至关重要的作用。在Oracle中,索引基本分为以下几种:B*Tree索引,反向索引,降序索引,位图索引,函数索引,interMedia全文索引等。本文主要就前6种索引进行分析,由于interMedia全文索引涉及的内容可以单独写一篇文章,所以不在此对其做分析。 首先给出各种索引的简要解释:
b*tree index:几乎所有的关系型数据库中都有b*tree类型索引,也是被最多使用的。其树结构与二叉树比较类似,根据rid快速定位所访问的行。 反向索引:反转了b*tree索引码中的字节,是索引条目分配更均匀,多用于并行服务器环境下,用于减少索引叶的竞争。
降序索引:8i中新出现的索引类型,针对逆向排序的查询。
位图索引:使用位图来管理与数据行的对应关系,多用于OLAP系统。
函数索引:这种索引中保存了数据列基于function返回的值,在select * from table where function(column)=value这种类型的语句中起作用。 2 各种索引的结构分析
2.1 B*Tree索引B*Tree索引是最常见的索引结构,默认建立的索引就是这种类型的索引。B*Tree索引在检索高基数数据列(高基数数据列是指该列有很多不同的值)时提供了最好的性能。当取出的行数占总行数比例较小时B-Tree索引比全表检索提供了更有效的方法。但当检查的范围超过表的10%时就不能提高取回数据的性能。B-Tree索引是基于二叉树的,由分支块(branch block)和叶块(leaf block)组成。在树结构中,位于最底层底块被称为叶块,包含每个被索引列的值和行所对应的rowid。在叶节点的上面是分支块,用来导航结构,包含了索引列(关键字)范围和另一索引块的地址。
假设我们要找索引中值为80的行,从索引树的最上层入口开始,定位到大于等于50,然后往左找,找到第2个分支块,定位为75-100,最后再定位到叶块上,找到80所对应的rowid,然后根据rowid去读取数据块获取数据。如果查询条件是范围选择的,比如where column >20 and column <80,那么会先定位到第一个包含20的叶块,然后横向查找其他的叶块,直到找到包含80的块为止,不用每次都从入口进去再重新定位。 2.2 反向索引
反向索引是B*Tree索引的一个分支,它的设计是为了运用在某些特定的环境下的。Oracle推出它的主要目的就是为了降低在并行服务器(Oracle Parallel Server)环境下索引叶块的争用。当B*Tree索引中有一列是由递增的序列号产生的话,那么这些索引信息基本上分布在同一个叶块,当用户修改或访问相似的列时,索引块很容易产生争用。反向索引中的索引码将会被分布到各个索引块中,减少了争用。反向索引反转了索引码中每列的字节,通过dump()函数我们可
以清楚得看见它做了什么。举个例子:1,2,3三个连续的数,用dump()函数看它们在Oracle内部的表示方法。 2.4 位图索引
位图索引主要用于决策支持系统或静态数据,不支持行级锁定。位图索引最好用于低cardinality列(即列的唯一值除以行数为一个很小的值,接近零),例如又一个“性别”列,列值有“Male”,“Female”,“Null”等3种,但一共有300万条记录,那么3/3000000约等于0,这种情况下最适合用位图索引。 位图索引可以是简单的(单列)也可以是连接的(多列),但在实践中绝大多数是简单的。在这些列上多位图索引可以与AND或OR操作符结合使用。位图索引使用位图作为键值,对于表中的每一数据行位图包含了TRUE(1)、FALSE(0)、或NULL值。位图索引的位图存放在B-Tree结构的页节点中。B-Tree结构使查找位图非常方便和快速。另外,位图以一种压缩格式存放,因此占用的磁盘空间比B-Tree索引要小得多。
如果搜索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来访问数据块。 2.5 函数索引
基于函数的索引也是8i以来的新产物,它有索引计算列的能力,它易于使用并且提供计算好的值,在不修改应用程序的逻辑上提高了查询性能。使用基于函数的索引有几个先决条件:
(1)必须拥有QUERY REWRITE(本模式下)或GLOBAL QUERY REWRITE(其他模式下)权限。
(2)必须使用基于成本的优化器,基于规则的优化器将被忽略。 (3)必须设置以下两个系统参数: QUERY_REWRITE_ENABLED=TRUE
QUERY_REWRITE_INTEGRITY=TRUSTED
可以通过alter system set,alter session set在系统级或线程级设置,也可以通过在init.ora添加实现。这里举一个基于函数的索引的例子: 3 各种索引的创建方法
(1)*Tree索引。
Create index indexname on tablename(columnname[columnname...])
(2)反向索引。
Create index indexname on tablename(columnname[columnname...]) reverse
(3)降序索引。
Create index indexname on tablename(columnname DESC[columnname...]) (4)位图索引。
Create BITMAP index indexname on tablename(columnname[columnname...]) (5)函数索引。
Create index indexname on tablename(functionname(columnname)) 注意:创建索引后分析要索引才能起作用。
analyze index indexname compute statistics; 4 各种索引使用场合及建议(1)B*Tree索引。
常规索引,多用于oltp系统,快速定位行,应建立于高cardinality列(即列的唯一值除以行数为一个很大的值,存在很少的相同值)。 (2)反向索引。
B*Tree的衍生产物,应用于特殊场合,在ops环境加序列增加的列上建立,不适合做区域扫描。 (3)降序索引。
B*Tree的衍生产物,应用于有降序排列的搜索语句中,索引中储存了降序排列的索引码,提供了快速的降序搜索。 (4)位图索引。
位图方式管理的索引,适用于OLAP(在线分析)和DSS(决策处理)系统,应建立于低cardinality列,适合集中读取,不适合插入和修改,提供比B*Tree索引更节省的空间。 (5)函数索引。
B*Tree的衍生产物,应用于查询语句条件列上包含函数的情况,索引中储存了经过函数计算的索引码值。可以在不修改应用程序的基础上能提高查询效率。
5.创建索引
默认创建的是B树索引
CREATE INDEX index_name on TABLE.COLUMN 语法选项
UNIQUE:用于指定唯一的索引(缺省为Nonunique) Schema:索引/表的所有者 Index:索引名 Table:表名 Column:列名
ASC/DESC:指示是按升序还是按降序创建索引 TABLESPACE:指定要在其中创建索引的表空间
PCTFREE:创建索引时为容纳新的索引项而在每块中保留的空间大小(以总空间
量减去块头后的百分比表示)
INITRANS:指定每块中预先分配的事务处理项的数目(缺省值和最小值为 2。) MAXTRANS:可以为每个块分配的事务处理项数(缺省值为 255。) STORAGE 子句:标识确定如何为索引分配区的存储子句
LOGGING:指定在重做日志文件中记录索引创建操作和在索引上执行的后续操作(这是缺省值。)
NOLOGGING:指定在重做日志文件中不记录创建操作和某些类型的数据加载操作 NOSORT:指定将行按升序存储在数据库中,这样,Oracle服务器在创建索引时不必对行进行排序 注
如果已为表空间定义了MINIMUM EXTENT,则索引的区大小将向上舍入为下一个更高的 MINIMUM EXTENT 值的倍数。
如果省略了 [NO]LOGGING 子句,索引的事件记录属性将缺省为表所驻留的表空间的事件记录属性。
不能为索引指定 PCTUSED。由于索引项必须按正确的顺序存储,所以用户无法控制何时在某一索引块中插入。
如果在数据未按关键字排序的情况下使用NOSORT关键字,语句将终止并显示错误。如果表上已经有多个DML操作,则该选项很可能无效。
如果可能,Oracle服务器使用现有索引创建新的索引。当新索引的关键字与现有索引键的主要部分对应时,就会发生这种情况。
6.创建索引的原则 创建索引时应考虑:
索引能够提高查询性能并降低DML操作速度。始终使易失表(volatile tables)所需的索引数保持最少。
将索引放在一个单独的表空间中,不要放在有还原段、临时段和表的表空间中。 对大型索引而言,避免生成重做日志可显著提高性能。请考虑使用NOLOGGING子句创建大型索引。
使用统一的区大小:块数是 5 的倍数或对表空间使用 MINIMUM EXTENT 大小 由于索引项比索引行小,所以索引块趋向于在每块中包含更多的项。因此,INITRANS在索引中通常比在对应的表中高。
9.重建索引
可能的重建情况:
需要将现有索引移到另外的表空间中。如果索引和表在同一表空间中或者需要跨磁盘重新分布对象时,可能需要执行此操作。
索引中包含很多已删除的项。这是滑动索引(如订单表中的订单号上的索引)存在的典型问题。
需要将现有正常索引转换成反向键索引。在从 Oracle 服务器的早期发行版移植应用程序时,可能会出现这种情况。
已通过 ALTER TABLE..MOVE TABLESPACE 命令将表移至其它表空间。? 特点:
将现有索引作为数据源建立新索引。
使用现有索引建立索引时无需排序(sort),从而使性能更佳。
在建立新索引后,删除旧索引。在重建期间,各自的表空间内需要有足够的空间以容纳新旧索引。
结果索引不包括任何已删除的项。因此,该索引可以更有效地使用空间。 在建立新索引的过程中,查询可继续使用现有索引。 语法:?
?ALTER INDEX [schema.] index REBUILD ?[ TABLESPACE tablespace ] ?[ PCTFREE integer ] ?[ INITRANS integer ] ?[ MAXTRANS integer ] ?[ storage-clause ]
?[ LOGGING| NOLOGGING ] ?[ REVERSE | NOREVERSE ] ALTER INDEX ...REBUILD 命令不能用于将位图索引更改为B树索引,反之亦然。 只能为B树索引指定REVERSE或NOREVERSE关键字。 注:关于REVERSE关键字,在baidu上搜到如下解释 反向索引
反向索引是建立在索引栏位值的反向值上的,可以使相临的记录在索引段里变得离散,可以减少某些DML操作引发的块竞争; 反向索引多建立在用序列号生成的栏位上,这样的栏位在普通索引中容易形成更多的层(设计过一些试验,但一直未观察到这种现象);
有两种产生方法:CREATE INDEX „ REVERSE; ALTER INDEX „ REVERSE; 反向索引适于WHERE中的等于或不等于的比较,对于范围查找(>,< between)是为力的。
Oracle9i允许在基表上进行并发操作的同时建立或重建索引,但不建议在此过程中执行大量的DML操作。 不能在临时表中重建索引
不能重建整个分区索引。必须分别重建每个分区或子分区。 也不能回收未用空间。
不能整个更改索引的PCTFREE参数值。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- sarr.cn 版权所有 赣ICP备2024042794号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务