当前位置:文档之家› Oracle 索引 详解

Oracle 索引 详解

Oracle 索引 详解
Oracle 索引 详解

Oracle 索引详解

https://www.doczj.com/doc/762190878.html,/tianlesoftware/article/details/5347098

一.索引介绍

1.1 索引的创建语法:

CREATE UNIUQE | BITMAP INDEX .

ON .

( | ASC | DESC,

| ASC | DESC,...)

TABLESPACE

STORAGE

LOGGING | NOLOGGING

COMPUTE STATISTICS

NOCOMPRESS | COMPRESS

NOSORT | REVERSE

PARTITION | GLOBAL PARTITION

相关说明

1)UNIQUE | BITMAP:指定UNIQUE为唯一值索引,BITMAP为位图索引,省略为B-Tree 索引。

2) | ASC | DESC:可以对多列进行联合索引,当为expression时即“基于函数的索引”

3)TABLESPACE:指定存放索引的表空间(索引和原表不在一个表空间时效率更高)

4)STORAGE:可进一步设置表空间的存储参数

5)LOGGING | NOLOGGING:是否对索引产生重做日志(对大表尽量使用NOLOGGING 来减少占用空间并提高效率)

6)COMPUTE STATISTICS:创建新索引时收集统计信息

7)NOCOMPRESS | COMPRESS:是否使用“键压缩”(使用键压缩可以删除一个键列中出现的重复值)

8)NOSORT | REVERSE:NOSORT表示与表中相同的顺序创建索引,REVERSE表示相

反顺序存储索引值

9)PARTITION | NOPARTITION:可以在分区表和未分区表上对创建的索引进行分区

1.2 索引特点:

第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。

第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。

第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。

第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。

1.3 索引不足:

第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。

第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。

第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。

1.4 应该建索引列的特点:

1)在经常需要搜索的列上,可以加快搜索的速度;

2)在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;

3)在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度;

4)在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的;

5)在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;

6)在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。

1.5 不应该建索引列的特点:

第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。

第二,对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。

第三,对于那些定义为blob数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。

第四,当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。

1.6 限制索引

限制索引是一些没有经验的开发人员经常犯的错误之一。在SQL中有很多陷阱会使一些索引无法使用。下面讨论一些常见的问题:

1.6.1 使用不等于操作符(<>、!=)

下面的查询即使在cust_rating列有一个索引,查询语句仍然执行一次全表扫描。

select cust_Id,cust_name from customers where cust_rating <> 'aa';

把上面的语句改成如下的查询语句,这样,在采用基于规则的优化器而不是基于代价的优化器(更智能)时,将会使用索引。

select cust_Id,cust_name from customers where cust_rating < 'aa' or cust_rating > 'aa';

特别注意:通过把不等于操作符改成OR条件,就可以使用索引,以避免全表扫描。

1.6.2 使用IS NULL 或IS NOT NULL

使用IS NULL 或IS NOT NULL同样会限制索引的使用。因为NULL值并没有被定义。在SQL语句中使用NULL会有很多的麻烦。因此建议开发人员在建表时,把需要索引的列设成NOT NULL。如果被索引的列在某些行中存在NULL值,就不会使用这个索引(除非索引是一个位图索引,关于位图索引在稍后在详细讨论)。

1.6.3 使用函数

如果不使用基于函数的索引,那么在SQL语句的WHERE子句中对存在索引的列使用函数时,会使优化器忽略掉这些索引。下面的查询不会使用索引(只要它不是基于函数的索引)select empno,ename,deptno from emp where trunc(hiredate)='01-MAY-81';

把上面的语句改成下面的语句,这样就可以通过索引进行查找。

select empno,ename,deptno from emp where hiredate<(to_date('01-MAY-81')+0.9999);

1.6.4 比较不匹配的数据类型

也是比较难于发现的性能问题之一。注意下面查询的例子,account_number是一个VARCHAR2类型,在account_number字段上有索引。

下面的语句将执行全表扫描:

select bank_name,address,city,state,zip from banks where account_number = 990354; Oracle可以自动把where子句变成to_number(account_number)=990354,这样就限制了索引的使用,改成下面的查询就可以使用索引:

select bank_name,address,city,state,zip from banks where account_number ='990354';

特别注意:不匹配的数据类型之间比较会让Oracle自动限制索引的使用,即便对这个查询执行Explain Plan也不能让您明白为什么做了一次“全表扫描”。

1.7 查询索引

查询DBA_INDEXES视图可得到表中所有索引的列表,注意只能通过USER_INDEXES的方法来检索模式(schema)的索引。访问USER_IND_COLUMNS视图可得到一个给定表中被索引的特定列。

1.8 组合索引

当某个索引包含有多个已索引的列时,称这个索引为组合(concatented)索引。在Oracle9i 引入跳跃式扫描的索引访问方法之前,查询只能在有限条件下使用该索引。比如:表emp 有一个组合索引键,该索引包含了empno、ename和deptno。在Oracle9i之前除非在where之句中对第一列(empno)指定一个值,否则就不能使用这个索引键进行一次范围扫描。

特别注意:在Oracle9i之前,只有在使用到索引的前导索引时才可以使用组合索引!

1.9 ORACLE ROWID

通过每个行的ROWID,索引Oracle提供了访问单行数据的能力。ROWID其实就是直接指向单独行的线路图。如果想检查重复值或是其他对ROWID本身的引用,可以在任何表中使用和指定rowid列。

1.10 选择性

使用USER_INDEXES视图,该视图中显示了一个distinct_keys列。比较一下唯一键的数量和表中的行数,就可以判断索引的选择性。选择性越高,索引返回的数据就越少。

1.11 群集因子(Clustering Factor)

Clustering Factor位于USER_INDEXES视图中。该列反映了数据相对于已建索引的列是否显得有序。如果Clustering Factor列的值接近于索引中的树叶块(leaf block)的数目,表中的数据就越有序。如果它的值接近于表中的行数,则表中的数据就不是很有序。

1.12 二元高度(Binary height)

索引的二元高度对把ROWID返回给用户进程时所要求的I/O量起到关键作用。在对一个索引进行分析后,可以通过查询DBA_INDEXES的B- level列查看它的二元高度。二元高度主要随着表的大小以及被索引的列中值的范围的狭窄程度而变化。索引上如果有大量被删除的行,它的二元高度也会增加。更新索引列也类似于删除操作,因为它增加了已删除键的数目。重建索引可能会降低二元高度。

1.13 快速全局扫描

从Oracle7.3后就可以使用快速全局扫描(Fast Full Scan)这个选项。这个选项允许Oracle 执行一个全局索引扫描操作。快速全局扫描读取B-树索引上所有树叶块。初始化文件中的DB_FILE_MULTIBLOCK_READ_COUNT参数可以控制同时被读取的块的数目。

1.14 跳跃式扫描

从Oracle9i开始,索引跳跃式扫描特性可以允许优化器使用组合索引,即便索引的前导列没有出现在WHERE子句中。索引跳跃式扫描比全索引扫描要快的多。

下面的比较他们的区别:

SQL> set timing on

SQL> create index TT_index on TT(teamid,areacode);

索引已创建。

已用时间: 00: 02: 03.93

SQL> select count(areacode) from tt;

COUNT(AREACODE)

---------------

7230369

已用时间: 00: 00: 08.31

SQL> select /*+ index(tt TT_index )*/ count(areacode) from tt;

COUNT(AREACODE)

---------------

7230369

已用时间: 00: 00: 07.37

1.15索引的类型

B-树索引位图索引HASH索引索引编排表

反转键索引基于函数的索引分区索引本地和全局索引

二.索引分类

Oracle提供了大量索引选项。知道在给定条件下使用哪个选项对于一个应用程序的性能来说非常重要。一个错误的选择可能会引发死锁,并导致数据库性能急剧下降或进程终止。而如果做出正确的选择,则可以合理使用资源,使那些已经运行了几个小时甚至几天的进程在几分钟得以完成,这样会使您立刻成为一位英雄。下面就将简单的讨论每个索引选项。

下面讨论的索引类型:

B树索引(默认类型)

位图索引

HASH索引

索引组织表索引

反转键(reverse key)索引

基于函数的索引

分区索引(本地和全局索引)

位图连接索引

2.1 B树索引(默认类型)

B树索引在Oracle中是一个通用索引。在创建索引时它就是默认的索引类型。B树索引可以是一个列的(简单)索引,也可以是组合/复合(多个列)的索引。B树索引最多可以包括32列。

在下图的例子中,B树索引位于雇员表的last_name列上。这个索引的二元高度为3;接下来,Oracle会穿过两个树枝块(branch block),到达包含有ROWID的树叶块。在每个树枝块中,树枝行包含链中下一个块的ID号。

树叶块包含了索引值、ROWID,以及指向前一个和后一个树叶块的指针。Oracle可以从两个方向遍历这个二叉树。B树索引保存了在索引列上有值的每个数据行的ROWID值。Oracle 不会对索引列上包含NULL值的行进行索引。如果索引是多个列的组合索引,而其中列上包含NULL值,这一行就会处于包含NULL值的索引列中,且将被处理为空(视为NULL)。

技巧:索引列的值都存储在索引中。因此,可以建立一个组合(复合)索引,这些索引可以直接满足查询,而不用访问表。这就不用从表中检索数据,从而减少了I/O量。

B-tree特点:

适合与大量的增、删、改(OLTP)

不能用包含OR操作符的查询;

适合高基数的列(唯一值多)

典型的树状结构;

每个结点都是数据块;

大多都是物理上一层、两层或三层不定,逻辑上三层;

叶子块数据是排序的,从左向右递增;

在分支块和根块中放的是索引的范围;

2.2 位图索引

位图索引非常适合于决策支持系统(Decision Support System,DSS)和数据仓库,它们不应该用于通过事务处理应用程序访问的表。它们可以使用较少到中等基数(不同值的数量)的列访问非常大的表。尽管位图索引最多可达30个列,但通常它们都只用于少量的列。

例如,您的表可能包含一个称为Sex的列,它有两个可能值:男和女。这个基数只为2,如果用户频繁地根据Sex列的值查询该表,这就是位图索引的基列。当一个表内包含了多个位图索引时,您可以体会到位图索引的真正威力。如果有多个可用的位图索引,Oracle就可以合并从每个位图索引得到的结果集,快速删除不必要的数据。

Bitmap t 特点:

适合与决策支持系统;

做UPDATE代价非常高;

非常适合OR操作符的查询;

基数比较少的时候才能建位图索引;

技巧:对于有较低基数的列需要使用位图索引。性别列就是这样一个例子,它有两个可能值:男或女(基数仅为2)。位图对于低基数(少量的不同值)列来说非常快,这是因为索引的尺寸相对于B树索引来说小了很多。因为这些索引是低基数的B树索引,所以非常小,因此您可以经常检索表中超过半数的行,并且仍使用位图索引。

当大多数条目不会向位图添加新的值时,位图索引在批处理(单用户)操作中加载表(插入操作)方面通常要比B树做得好。当多个会话同时向表中插入行时不应该使用位图索引,在大多数事务处理应用程序中都会发生这种情况。

示例

下面来看一个示例表PARTICIPANT,该表包含了来自个人的调查数据。列Age_Code、Income_Level、Education_Level和Marital_Status都包括了各自的位图索引。下图显示了每个直方图中的数据平衡情况,以及对访问每个位图索引的查询的执行路径。图中的执行路径显示了有多少个位图索引被合并,可以看出性能得到了显著的提高。

如上图图所示,优化器依次使用4个单独的位图索引,这些索引的列在WHERE子句中被

引用。每个位图记录指针(例如0或1),用于指示表中的哪些行包含位图中的已知值。有了这些信息后,Oracle就执行BITMAP AND操作以查找将从所有4个位图中返回哪些行。该值然后被转换为ROWID值,并且查询继续完成剩余的处理工作。注意,所有4个列都有非常低的基数,使用索引可以非常快速地返回匹配的行。

技巧:在一个查询中合并多个位图索引后,可以使性能显著提高。位图索引使用固定长度的数据类型要比可变长度的数据类型好。较大尺寸的块也会提高对位图索引的存储和读取性能。

下面的查询可显示索引类型。

SQL> select index_name, index_type from user_indexes;

INDEX_NAME INDEX_TYPE

------------------------------ ----------------------

TT_INDEX NORMAL

IX_CUSTADDR_TP NORMAL

B树索引作为NORMAL列出;而位图索引的类型值为BITMAP。

技巧:如果要查询位图索引列表,可以在USER _INDEXES视图中查询index_type列。

建议不要在一些联机事务处理(OLTP)应用程序中使用位图索引。B树索引的索引值中包含

ROWID,这样Oracle就可以在行级别上锁定索引。位图索引存储为压缩的索引值,其中包含了一定范围的ROWID,因此Oracle必须针对一个给定值锁定所有范围内的ROWID。这种锁定类型可能在某些DML语句中造成死锁。SELECT语句不会受到这种锁定问题的影响。位图索引的使用限制:

基于规则的优化器不会考虑位图索引。

当执行ALTER TABLE语句并修改包含有位图索引的列时,会使位图索引失效。

位图索引不包含任何列数据,并且不能用于任何类型的完整性检查。

位图索引不能被声明为唯一索引。

位图索引的最大长度为30。

技巧:不要在繁重的OLTP环境中使用位图索引

2.3 HASH索引

使用HASH索引必须要使用HASH集群。建立一个集群或HASH集群的同时,也就定义了一个集群键。这个键告诉Oracle如何在集群上存储表。在存储数据时,所有与这个集群键相关的行都被存储在一个数据库块上。如果数据都存储在同一个数据库块上,并且将HASH 索引作为WHERE子句中的确切匹配,Oracle就可以通过执行一个HASH函数和I/O来访问数据——而通过使用一个二元高度为4的B树索引来访问数据,则需要在检索数据时使用4个I/O。如下图所示,其中的查询是一个等价查询,用于匹配HASH列和确切的值。Oracle可以快速使用该值,基于HASH函数确定行的物理存储位置。

HASH索引可能是访问数据库中数据的最快方法,但它也有自身的缺点。集群键上不同值的数目必须在创建HASH集群之前就要知道。需要在创建HASH集群的时候指定这个值。低估了集群键的不同值的数字可能会造成集群的冲突(两个集群的键值拥有相同的HASH值)。这种冲突是非常消耗资源的。冲突会造成用来存储额外行的缓冲溢出,然后造成额外的I/O。如果不同HASH值的数目已经被低估,您就必须在重建这个集群之后改变这个值。

ALTER CLUSTER命令不能改变HASH键的数目。HASH集群还可能浪费空间。如果无法确定需要多少空间来维护某个集群键上的所有行,就可能造成空间的浪费。如果不能为集群的未来增长分配好附加的空间,HASH集群可能就不是最好的选择。如果应用程序经常在集群表上进行全表扫描,HASH集群可能也不是最好的选择。由于需要为未来的增长分配好集群的剩余空间量,全表扫描可能非常消耗资源。

在实现HASH集群之前一定要小心。您需要全面地观察应用程序,保证在实现这个选项之前已经了解关于表和数据的大量信息。通常,HASH对于一些包含有序值的静态数据非常有效。

技巧:HASH索引在有限制条件(需要指定一个确定的值而不是一个值范围)的情况下非常有用。

2.4 索引组织表

索引组织表会把表的存储结构改成B树结构,以表的主键进行排序。这种特殊的表和其他类型的表一样,可以在表上执行所有的DML和DDL语句。由于表的特殊结构,ROWID并没有被关联到表的行上。

对于一些涉及精确匹配和范围搜索的语句,索引组织表提供了一种基于键的快速数据访问机制。基于主键值的UPDATE和DELETE语句的性能也同样得以提高,这是因为行在物理上有序。由于键列的值在表和索引中都没有重复,存储所需要的空间也随之减少。

如果不会频繁地根据主键列查询数据,则需要在索引组织表中的其他列上创建二级索引。不会频繁根据主键查询表的应用程序不会了解到使用索引组织表的全部优点。对于总是通过对主键的精确匹配或范围扫描进行访问的表,就需要考虑使用索引组织表。

技巧:可以在索引组织表上建立二级索引。

2.5 反转键索引

当载入一些有序数据时,索引肯定会碰到与I/O相关的一些瓶颈。在数据载入期间,某部分索引和磁盘肯定会比其他部分使用频繁得多。为了解决这个问题,可以把索引表空间存放在

能够把文件物理分割在多个磁盘上的磁盘体系结构上。

为了解决这个问题,Oracle还提供了一种反转键索引的方法。如果数据以反转键索引存储,这些数据的值就会与原先存储的数值相反。这样,数据1234、1235和1236就被存储成4321、5321和6321。结果就是索引会为每次新插入的行更新不同的索引块。

技巧:如果您的磁盘容量有限,同时还要执行大量的有序载入,就可以使用反转键索引。不可以将反转键索引与位图索引或索引组织表结合使用。因为不能对位图索引和索引组织表进行反转键处理。

2.6 基于函数的索引

可以在表中创建基于函数的索引。如果没有基于函数的索引,任何在列上执行了函数的查询都不能使用这个列的索引。例如,下面的查询就不能使用JOB列上的索引,除非它是基于函数的索引:

select *from emp where UPPER(job) = 'MGR';

下面的查询使用JOB列上的索引,但是它将不会返回JOB列具有Mgr或mgr值的行:select *from emp where job = 'MGR';

可以创建这样的索引,允许索引访问支持基于函数的列或数据。可以对列表达式UPPER(job)创建索引,而不是直接在JOB列上建立索引,如:

create index EMP$UPPER_JOB on emp(UPPER(job));

尽管基于函数的索引非常有用,但在建立它们之前必须先考虑下面一些问题:

能限制在这个列上使用的函数吗?如果能,能限制所有在这个列上执行的所有函数吗

是否有足够应付额外索引的存储空间?

在每列上增加的索引数量会对针对该表执行的DML语句的性能带来何种影响?

基于函数的索引非常有用,但在实现时必须小心。在表上创建的索引越多,INSERT、UPDATE和DELETE语句的执行就会花费越多的时间。

注意:对于优化器所使用的基于函数的索引来说,必须把初始参数QUERY _REWRITE _ ENABLED设定为TRUE。

示例:

select count(*)from sample where ratio(balance,limit) >.5;

Elapsed time: 20.1 minutes

create index ratio_idx1 on sample (ratio(balance, limit));

select count(*)from sample where ratio(balance,limit) >.5;

Elapsed time: 7 seconds!!!

2.7 分区索引

分区索引就是简单地把一个索引分成多个片断。通过把一个索引分成多个片断,可以访问更小的片断(也更快),并且可以把这些片断分别存放在不同的磁盘驱动器上(避免I/O问题)。B 树和位图索引都可以被分区,而HASH索引不可以被分区。可以有好几种分区方法:表被分区而索引未被分区;表未被分区而索引被分区;表和索引都被分区。不管采用哪种方法,都必须使用基于成本的优化器。分区能够提供更多可以提高性能和可维护性的可能性

有两种类型的分区索引:本地分区索引和全局分区索引。每个类型都有两个子类型,有前缀索引和无前缀索引。表各列上的索引可以有各种类型索引的组合。如果使用了位图索引,就必须是本地索引。把索引分区最主要的原因是可以减少所需读取的索引的大小,另外把分区放在不同的表空间中可以提高分区的可用性和可靠性。

在使用分区后的表和索引时,Oracle还支持并行查询和并行DML。这样就可以同时执行多个进程,从而加快处理这条语句。

2.7.1.本地分区索引(通常使用的索引)

可以使用与表相同的分区键和范围界限来对本地索引分区。每个本地索引的分区只包含了它所关联的表分区的键和ROWID。本地索引可以是B树或位图索引。如果是B树索引,它可以是唯一或不唯一的索引。

这种类型的索引支持分区独立性,这就意味着对于单独的分区,可以进行增加、截取、删除、分割、脱机等处理,而不用同时删除或重建索引。Oracle自动维护这些本地索引。本地索引分区还可以被单独重建,而其他分区不会受到影响。

2.7.1.1 有前缀的索引

有前缀的索引包含了来自分区键的键,并把它们作为索引的前导。例如,让我们再次回顾participant表。在创建该表后,使用survey_id和survey_date这两个列进行范围分区,然后在survey_id列上建立一个有前缀的本地索引,如下图所示。这个索引的所有分区都被等价划分,就是说索引的分区都使用表的相同范围界限来创建。

技巧:本地的有前缀索引可以让Oracle快速剔除一些不必要的分区。也就是说没有包含WHERE条件子句中任何值的分区将不会被访问,这样也提高了语句的性能。

2.7.1.2 无前缀的索引

无前缀的索引并没有把分区键的前导列作为索引的前导列。若使用有同样分区键(survey_id 和survey_date)的相同分区表,建立在survey_date列上的索引就是一个本地的无前缀索引,如下图所示。可以在表的任一列上创建本地无前缀索引,但索引的每个分区只包含表的相应分区的键值。

如果要把无前缀的索引设为唯一索引,这个索引就必须包含分区键的子集。在这个例子中,我们必须把包含survey和(或)survey_id的列进行组合(只要survey_id不是索引的第一列,它就是一个有前缀的索引)。

技巧:对于一个唯一的无前缀索引,它必须包含分区键的子集。

2.7.2. 全局分区索引

全局分区索引在一个索引分区中包含来自多个表分区的键。一个全局分区索引的分区键是分区表中不同的或指定一个范围的值。在创建全局分区索引时,必须定义分区键的范围和值。全局索引只能是B树索引。Oracle在默认情况下不会维护全局分区索引。如果一个分区被截取、增加、分割、删除等,就必须重建全局分区索引,除非在修改表时指定ALTER TABLE 命令的UPDATE GLOBAL INDEXES子句。

2.7.2.1 有前缀的索引

通常,全局有前缀索引在底层表中没有经过对等分区。没有什么因素能限制索引的对等分区,但Oracle在生成查询计划或执行分区维护操作时,并不会充分利用对等分区。如果索引被对等分区,就必须把它创建为一个本地索引,这样Oracle可以维护这个索引,并使用它来删除不必要的分区,如下图所示。在该图的3个索引分区中,每个分区都包含指向多个表分区中行的索引条目。

分区的、全局有前缀索引

技巧:如果一个全局索引将被对等分区,就必须把它创建为一个本地索引,这样Oracle可以维护这个索引,并使用它来删除不必要的分区。

2.7.2.2 无前缀的索引

Oracle不支持无前缀的全局索引。

2.8 位图连接索引

位图连接索引是基于两个表的连接的位图索引,在数据仓库环境中使用这种索引改进连接维度表和事实表的查询的性能。创建位图连接索引时,标准方法是连接索引中常用的维度表和事实表。当用户在一次查询中结合查询事实表和维度表时,就不需要执行连接,因为在位图连接索引中已经有可用的连接结果。通过压缩位图连接索引中的ROWID进一步改进性能,并且减少访问数据所需的I/O数量。

创建位图连接索引时,指定涉及的两个表。相应的语法应该遵循如下模式:

create bitmap index FACT_DIM_COL_IDX on FACT(DIM.Descr_Col)from FACT, DIM where FACT.JoinCol = DIM.JoinCol;

位图连接的语法比较特别,其中包含FROM子句和WHERE子句,并且引用两个单独的表。索引列通常是维度表中的描述列——就是说,如果维度是CUSTOMER,并且它的主键是CUSTOMER_ID,则通常索引Customer_Name这样的列。如果事实表名为SALES,可以使用如下的命令创建索引:

create bitmap index SALES_CUST_NAME_IDX

on SALES(CUSTOMER.Customer_Name)from SALES, CUSTOMER

where SALES.Customer_ID=CUSTOMER.Customer_ID;

如果用户接下来使用指定Customer_Name列值的WHERE子句查询SALES和CUSTOMER表,优化器就可以使用位图连接索引快速返回匹配连接条件和

Customer_Name条件的行。

位图连接索引的使用一般会受到限制:

1)只可以索引维度表中的列。

2)用于连接的列必须是维度表中的主键或唯一约束;如果是复合主键,则必须使用连接中的每一列。

3)不可以对索引组织表创建位图连接索引,并且适用于常规位图索引的限制也适用于位图连接索引。

注:本文整理自《Oracle Database 10g 性能调整与优化》

------------------------------------------------------------------------------ Blog:https://www.doczj.com/doc/762190878.html,/tianlesoftware

网上资源:https://www.doczj.com/doc/762190878.html,

相关视频:https://www.doczj.com/doc/762190878.html,/tianlesoftware/archive/2009/11/27/4886500.aspx DBA1 群:62697716(满); DBA2 群:62697977(满)

DBA3 群:63306533; 聊天群:40132017

Oracle 索引组织表与标准表

Oracle 索引组织表与标准表 索引组织表也称为IOT ,索引组织表实际上一个表,不过它的存储结构不像普通的表那样采用堆组织方式,而是采用索引的组织方式。对于普通表而言,其存储结构是将记录无序地存放在数据段中,而索引化组织表是将记录按照某个主键列进行排序后,再以B 树的组织方式存放在数据段中。 由于整条记录都被保存在索引中,所以索引组织表不需要使用ROWID 来确定记录的位置。在索引组织表中只需要知道主键列的值,就能够直接找到相应记录的完整内容。因此,索引组织表提供了快速的、基于主键的对表中数据快速访问。但是,这是以牺牲插入和更新性能为代价的。图9-6所示示意性地列出了索引组织表与标准表之间的区别。 ROWID 普通表索引索引表 主键行头非主键列 图9-6 索引组织表与标准堆表的对比 对于普通表而言,表、索引数据是分别存放在表段、索引段,要占用更多空间;而对于索引表而言,主键列和非主键列的数据都被存放在主键索引段中。当经常要使用主键列定义表数据时,应该建立索引表。使用索引表,一方面降低了磁盘和内存空间占用。另一方面也可以提高访问性能。 建立索引表也是使用CREATE TABLE 语句完成的。需要注意,建立索引组织表时,必须指定ORGANIZATION INDEX 关键字,并且在索引组织表中必须定义主键约束。例如,下面的语句建立一个索引组织的EMPLOYEES 表: SQL> create table employees( 2 empno number(5) primary key, 3 ename varchar2(15) not null, 4 job varchar2(10), 5 hiredate date default (sysdate), 6 sal number(7,2), 7 deptno number(3) not null 8 ) organization index 9 tablespace users; 表已创建。

Oracle索引分析与查询优化

龙源期刊网 https://www.doczj.com/doc/762190878.html, Oracle索引分析与查询优化 作者:崔黎明志远李婧 来源:《数字技术与应用》2016年第07期 摘要:Oracle是目前国内在大型数据存储中用得比较多的一种关系型数据库,磁盘阵列技术(RAID)和集群技术(RAC)的运用,使Oracle在处理数据效率和数据安全上有非常大的提高,在国内交通、电力,通信和金融等重要领域都有广泛的用途。本文基于Oracle 11g版本,对Rowid和索引的原理机制做出分析,并论述利用这些原理对大型数据表查询的优化。 关键词:Oracle Rowid 索引查询 中图分类号:TP311.13 文献标识码:A 文章编号:1007-9416(2016)07-0234-02 在逻辑上,Oracle是由多个表空间构成的,在新建一个表空间的时候,必须指定存储的文件,可以指向多个存储在不同磁盘上的数据。表空间下面分为段、区、块。新建一张表的时候,Oracle数据库就会为它创建一个段。所谓区就是指连续的块(block)构成的空间,一般区包含8个空块,block是Oracle数据库最小的数据空间,一般为8k或16k,当开始往这个表中插入数据的时候,Oralce数据库会自动为这个表分配一个区,并把数据不断往此区进行填充,当数据填满此区后,Oralce数据库会重新为该表分配一个区而不是一个段。实际上,对于我们不同的查询过程中,就是通过一些谓词过滤条件,从对应的数据块中获取正确的一行数据或多行数据。如何快速定位到该数据行,是一个数据库学习者不断探索的方向。 1 Rowid 1.1 简介 从字面上理解是行标识的意思,它是Oracle数据库中数据表的一个伪列,用于存放该表中每一行数据的地址,在8i版本之前,Oracle采用受限制的rowid,它是由数据文件编号,块编号和数据在该块内的偏移量这三个部分构成,长度为6个字节,因此在8i之前的版本中,每 个数据库最多可以包含1022个文件,每个文件最多能有4m个数据块,而每个数据库最多能 存储64k条记录。为了突破长度的限制和解决其他一些缺陷,Oracle数据库引入了这样一个概念:相对文件号。它的主要特点是改变之前rowid中数据文件编号是整个数据库范围组成的表空间,即文件编号为5的文件不再是数据库中编号为5的数据文件,而是表空间中对应编号的数据文件。如下图1所示为Oracle11g中一个普通表的rowid。 从该图1中可以看到rowid共有18位,分为四部分,格式为:AAAAAABBBCCCCCCDDD,其中AAAAAA六位表示dataobjectid,根据这个id可以确定该行数据在哪个段中;BBB三位表示相对文件号,通过这个字段号可以用来确定该行数据的绝 对文件号;CCCCCC六位表示datablocknumber,它是相对于datafile的编号;最后三位DDD

oracle索引基本分类

oracle索引基本分类法分类 逻辑上: Single column 单行索引 Concatenated 多行索引 Unique 唯一索引 NonUnique 非唯一索引 Function-based函数索引 Domain 域索引 物理上: Partitioned 分区索引 NonPartitioned 非分区索引 B-tree: Normal 正常型B树 Rever Key 反转型B树 Bitmap 位图索引 索引结构: B-tree: 适合与大量的增、删、改(OLTP); 不能用包含OR操作符的查询; 适合高基数的列(唯一值多) 典型的树状结构; 每个结点都是数据块; 大多都是物理上一层、两层或三层不定,逻辑上三层; 叶子块数据是排序的,从左向右递增; 在分支块和根块中放的是索引的范围; Bitmap: 适合与决策支持系统; 做UPDATE代价非常高; 非常适合OR操作符的查询; 基数比较少的时候才能建位图索引; 树型结构: 索引头 开始ROWID,结束ROWID(先列出索引的最大范围) BITMAP 每一个BIT对应着一个ROWID,它的值是1还是0,如果是1,表示着BIT 对应的ROWID有值; =============================================== ======================

Oracle的索引主要包含两类:BTree和位图索引。默认情况下大多使用Btree 索引,该索引就是通常所见唯一索引、聚簇索引等等,Btree用在OLTP,加快查询速度。位图索引是Oracle的比较引人注目的地方,其主要用在OLAP(联机数据分析)方面,也就是数据仓库方面用到,目的是在加快查询速度是,节省存储空间。通常情况下,索引都要耗费比较大的存储空间,位图采用了压缩技术实现磁盘空间缩减。Btree用在高基数(即列的数据相异度大),位图用在低基数列。位图索引的基本原理是在索引中使用位图而不是列值。通常在事实表和维表的键之间有很低的集的势(cardinality),使用位图索引,存储更为有效,与B*Tree 索引比较起来,只需要更少的存储空间,这样每次读取可以读到更多的记录,而且与B*Tree索引相比,位图索引将比较,连接和聚集都变成了位算术运算,大大减少了运行时间,从而得到性能上的极大的提升。 在Oracle中如何合理的使用位图索引?以下的几个事项应该考虑。 *如果要使用位图索引,初始化参数STAR_TRANSFORMATION_ENABLED 应该设置为TRUE. *优化模式应该是CBO。对于数据仓库的环境中,总是应该考虑使用CBO (COST-BASEDOPTIMIZER)。 *位图索引应该建立在每一个事实表的外键列上。(这只是一个一般的规则.) 此外,对于数据表中的cardinality如何客观的确定也是一个问题,一万条数据中只包含3个值的集和算是低的了,那么一亿条记录中包含3万条记录算不算低的呢?对于这样的情况,建议几行一下数据的模拟测试,一般来说,在数据仓库环境中,位图索引的性能要好于B*Tree索引。还要注意位图索引不是为OLTP 数据库设计的,不应该在OLTP数据库中大量的使用它,尤其是对那些有更新操作的表。 ==================================================================== ========== B*Tree索引 B*Tree索引是最常见的索引结构,默认建立的索引就是这种类型的索引。B*Tree索引在检索高基数数据列(高基数数据列是指该列有很多不同的值)时提供了最好的性能。当取出的行数占总行数比例较小时B-Tree索引比全表检索提供了更有效的方法。但当检查的范围超过表的10%时就不能提高取回数据的性能。B-Tree索引是基于二叉树的,由分支块(branch block)和叶块(leaf block)组成。在树结构中,位于最底层底块被称为叶块,包含每个被索引列的值和行所对应的rowid。在叶节点的上面是分支块,用来导航结构,包含了索引列(关键字)范围和另一索引块的地址,如图26-1所示。

Oracle索引原理

Oracle数据库中的索引详解 一、ROWID的概念 存储了row在数据文件中的具体位置:64位编码的数据,A-Z, a-z, 0-9, +, 和/,row在数据块中的存储方式 SELECT ROWID, last_name FROM hr.employees WHERE department_id = 20; 比如:OOOOOOFFFBBBBBBRRR OOOOOO:data object number, 对应dba_objects.data_object_id FFF:file#, 对应v$datafile.file# BBBBBB:block# RRR:row# Dbms_rowid包 SELECT dbms_rowid.rowid_block_number('AAAGFqAABAAAIWEAAA') from dual; 具体到特定的物理文件 二、索引的概念 1、类似书的目录结构 2、Oracle 的“索引”对象,与表关联的可选对象,提高SQL查询语句的速度 3、索引直接指向包含所查询值的行的位置,减少磁盘I/O 4、与所索引的表是相互独立的物理结构 5、Oracle 自动使用并维护索引,插入、删除、更新表后,自动更新索引 6、语法:CREA TE INDEX index ON table (column[, column]...); 7、B-tree结构(非bitmap): [一]了解索引的工作原理: 表:emp

目标:查询Frank的工资salary 建立索引:create index emp_name_idx on emp(name);

[试验]测试索引的作用: 1. 运行/rdbms/admin/utlxplan 脚本 2. 建立测试表 create table t as select * from dba_objects; insert into t select * from t; create table indextable as select rownum id,owner,object_name,subobject_name, object_id,data_object_id,object_type,created from t; 3. set autotrace trace explain 4. set timing on 5. 分析表,可以得到cost 6. 查询object_name=’DBA_INDEXES’ 7. 在object_name列上建立索引 8. 再查询 [思考]索引的代价: 插入,更新 三、唯一索引 1、何时创建:当某列任意两行的值都不相同 2、当建立Primary Key(主键)或者Unique constraint(唯一约束)时,唯一索引将被自动建立 3、语法:CREA TE UNIQUE INDEX index ON table (column); 4、演示

oracle数据库索引的理解与总结

索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。 例如这样一个查询:SELECT * FROM TABLE1 WHERE ID = 44。如果没有索引,必须遍历整个表,直到ID等于44的这一行被找到为止;有了索引之后(必须是在ID这一列上建立的索引),直接在索引里面找44(也就是在ID这一列找),就可以得知这一行的位置,也就是找到了这一行。可见,索引是用来定位的。 建立索引的目的是加快对表中记录的查找或排序。为表设置索引要付出代价的:一是增加了数据库的存储空间,二是在插入和修改数据时要花费较多的时间(因为索引也要随之变动)。 虽然建立索引能加快对表中记录的查询或者排序速度,但是并不是索引建得越多越好,这就需要我们了解使用索引过程中,索引的一些优点以及缺陷: 使用索引的好处: 创建索引可以大大提高系统的性能: 第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。 第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。 第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。 第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。使用索引的一些不足: 第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。 第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。 索引是建立在数据库表中的某些列的上面。在创建索引的时候,应该考虑在哪些列上可以创建索引,在哪些列上不能创建索引。一般来说,应该在这些列上创建索引: ?在经常需要搜索的列上,可以加快搜索的速度;在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构; ?在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度; ?在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的; ?在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间; ?在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。 同样,对于有些列不应该创建索引。一般来说,不应该创建索引的的这些列具有下列特点: ?对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。 ?对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了

Oracle索引介绍

Oracle索引简单介绍 更多Oracle资料下载,请收藏https://www.doczj.com/doc/762190878.html,

一、引言 对数据库索引的关注从未淡出我的们的讨论,那么数据库索引是什么样的?聚集索引与非聚集索引有什么不同?希望本文对各位同仁有一定的帮助。有不少存疑的地方,诚心希望各位不吝赐教指正,共同进步。 二、B-Tree 我们常见的数据库系统,其索引使用的数据结构多是B-Tree或者B+Tree。例如,MsSql使用的是B+Tree,Oracle及Sysbase使用的是B-Tree。所以在最开始,简单地介绍一下 B-Tree。 B-Tree不同于Binary Tree(二叉树,最多有两个子树),一棵M阶的B-Tree满足以下条件:1)每个结点至多有M个孩子; 2)除根结点和叶结点外,其它每个结点至少有M/2个孩子; 3)根结点至少有两个孩子(除非该树仅包含一个结点); 4)所有叶结点在同一层,叶结点不包含任何关键字信息; 5)有K个关键字的非叶结点恰好包含K+1个孩子; 另外,对于一个结点,其内部的关键字是从小到大排序的。以下是B-Tree(M=4)的样例:

对于每个结点,主要包含一个关键字数组Key[],一个指针数组(指向儿子)Son[]。在B-Tree 内,查找的流程是:使用顺序查找(数组长度较短时)或折半查找方法查找Key[]数组,若找到关键字K,则返回该结点的地址及K在Key[]中的位置;否则,可确定K在某个Key[i]和Key[i+1]之间,则从Son[i]所指的子结点继续查找,直到在某结点中查找成功;或直至找到叶结点且叶结点中的查找仍不成功时,查找过程失败。 接着,我们使用以下图片演示如何生成B-Tree(M=4,依次插入1~6): 从图可见,当我们插入关键字4时,由于原结点已经满了,故进行分裂,基本按一半的原则进行分裂,然后取出中间的关键字2,升级(这里是成为根结点)。其它的依类推,就是这样一个大概的过程。 三、数据库索引 1.什么是索引 在数据库中,索引的含义与日常意义上的“索引”一词并无多大区别(想想小时候查字典),它是用于提高数据库表数据访问速度的数据库对象。 A)索引可以避免全表扫描。多数查询可以仅扫描少量索引页及数据页,而不是遍历所有数据页。B)对于非聚集索引,有些查询甚至可以不访问数据页。 C)聚集索引可以避免数据插入操作集中于表的最后一个数据页。

oracle11g基于SQL的优化之索引优化篇

Oracle11g 基于SQL语句性能优化 通过索引对SQL进行优化 主讲人:马飞 所在部门:运维部

一、概述 本文所介绍的索引案例是在使用的是Oracle11g 11.2.0.4 数据库运行的。索引是使用最为普遍的一种优化SQL的方法,不同索引均有各自的优缺点。实际优化中需要综合考虑各种环境因素对运行慢的SQL进行优化。常见环境因素有:数据库表及索引的统计信息、列的柱状图,优化器的模式,表上是否有触发器,表上是否创建了物化视图日志,SQL语句是否使用提示符,当前会话的等待事件等。 Oracle数据库中索引可分为B-TREE索引、BitMap索引、全文索引三大类。按索引列的数量不同可分为,单列索引,多列索引。按列值是否唯一可分为唯一索引和非唯一性索引。 二、B-TREE索引 B-TREE索引常常用在OLTP数据库中,为了提高查询性,但同时一个表中索引数据多时会影响DML语句的性能,所以需要全面考虑增加索引后利弊。 2.1索引分类 主键索引、唯一键索引、非唯一键索引、多列组合索引。当表在创建主键时系统会自动为主键列或列的组合上创建唯一索引,主键索引性能最好。其它索引性能好坏取决于单列或多列的数据选择性,如果索引访问的数据小,性能相对较高,因为访问索引和表的块较少因而性能好。 2.2扫描方式 索引唯一扫描、索引范围扫描,全索引扫描,快速全索引扫描,索引跳跃扫描。 2.3上机实践 2.3.1 索引唯一扫描例子:

unique.txt 注意:由于唯一索引的列中可为空值。如果查询条件中有如下写法,则无法走索引扫描。因为b-tree索引中不存储空值。 (1)select * from tab where col is null (2)select * from tab where col is not null (3)select count(0) from tab; 其中(3)中的语句是否走索引取决于唯一索引的列上是否为非空,如果是非空,则会走“INDEX FAST FULL SCAN”快速索引扫描(采用并行索引扫描方式进行取读索引块,效率非常高)。 2.3.2 索引范围扫描例子 在非唯一性索引上的扫描通常都采用索引范围的扫描方式进行。 scan.txt scan2.txt 2.3.3 全索引扫描例子 全索引扫描指的是查询语句的所有列均在索引列中,同时需要访问全表的数据时使用。 indexfull.txt 2.3.4 快速全索引扫描例子 fast_fullscan.txt 2.3.5 索引跳跃扫描例子 skip.txt 2.4索引利弊 优点:当访问表中少量数据时可以提高查询的性能。

Oracle视图中建立索引的注意事项

Oracle视图中建立索引的注意事项 在视图上创建索引需要三个条件: 一、视图必须绑定到架构。 要做到这点,在 CREATE VIEW 语句中,必须加上 WITH SCHEMABINDING,如果是使用企业管理器,则在设计界面的空白处点击右键,属性,选中“绑定到架构”。 二、索引必须是唯一索引。 要做到这点,在 CREATE INDEX 中必须指定 UNIQUE。 三、索引必须是聚集索引。 要做到这点,在 CREATE INDEX 中必须指定 CLUSTERED。 例: CREATE VIEW viewFoo WITH SCHEMABINDING AS SELECT id... CREATE UNIQUE CLUSTERED INDEX index_viewFoo ON viewFoo(id) 在视图上创建聚集索引之前,该视图必须满足下列要求: 当执行 CREATE VIEW 语句时,ANSI_NULLS 和 QUOTED_IDENTIFIER 选项必须设置为 ON。OBJECTPROPERTY 函数通 过 ExecIsAnsiNullsOn 或 ExecIsQuotedIdentOn 属性为视图报告此信息。 为执行所有 CREATE TABLE 语句以创建视图引用的表,ANSI_NULLS 选项必须设置为 ON。 视图不能引用任何其它视图,只能引用基表。 视图引用的所有基表必须与视图位于同一个数据库中,并且所有者也与视图相同。 必须使用 SCHEMABINDING 选项创建视图。SCHEMABINDING 将视图绑定到基础基表的架构。 必须已使用 SCHEMABINDING 选项创建了视图中引用的用户定义的函数。 表和用户定义的函数必须由 2 部分的名称引用。不允许使用 1 部分、3 部分和 4 部分的名称。

Oracle 创建索引

Oracle创建索引 Oracle在创建索引时要遵循以下的原则: ●平衡查询和DML的需要。在易挥发(DML操作频繁)的表上尽量减少索引的数量, 因为索引虽然加快了查询的速度,但却降低了DML操作速度。 ●将其放入单独的表空间,不要与表、临时段或还原(回滚)段放在一个表空间,因为索 引段会与这些段竞争输入/输出(I/O)。 ●使用统一的EXTENT尺寸:数据块尺寸的5倍,或表空间的MINIMUM EXTENT的尺 寸。这样做的目的是为了减少系统的转换时间。 ●对大索引可以考虑使用NOLOGGING。这样做的目的是通过减少REDO操作来提高系 统的效率,但是如果一旦系统发生崩溃,则该索引一般是无法进行完全灰度的。不过问题也不是很大,因为真正的数据还在表中,所以可以通过重建该索引来恢复与之前完全相同的效果。 ●索引的INITRANS参数通常应该比相对应表的高。以为索引项要比表中的数据行小的 多,所以一个数据块可以存放更多的索引项(记录)。 创建索引的命令格式: CREATE (UNIQUE|BITMAP) INDEX [用户名.]索引名 ON [用户名.]表名 (列名[ASC | DESC] [,列名[ASC| DESC ] ]…) [TABLESPACE 表空间名] [PCTFREE 正整型数] [INITRANS 正整型数] [MAXTRANS 正整型数] [存储子句] [LOGGING | NOLOGGING] [NOSORT] 其中, ●UNIQUE:说明该索引是唯一索引,默认是非唯一的 ●ASC:说明所创建的索引为升序 ●DESC:说明所创建的索引为降序 ●表空间名:说明将要创建的索引的表空间名 ●PCTFREE:在创建索引时每一个块中预留的空间 ●INITRANS:在每一个块中预分配的事物记录数,默认值为2 ●MAXTRANS:在每一个块中可以分配的事物记录数的上限,默认为255 ●存储子句:说明在索引中EXTENTS怎样分配 ●LOGGING:说明在创建索引是和以后的索引操作中要记录联机重做日志文件(默认)●NOLOGGING:说明索引的创建和一些数据装入操作将不记录联机重做日志文件 ●NOSORT:数据库中所存的数据行已经按升序排好,因此在创建索引时不需要再排序了●PCTUSED:在索引中不能说明该参数。因为索引记录必须以正确的顺序存放,所以用 户不能控制何时向索引块中插入索引数据行 使用数据字典的dba_indexes获取有关scott用户的索引基于表、所在的表空间、索引的类型和索引的状态等信息。 SQL> select index_name,table_name,tablespace_name,index_type, uniqueness,status from dba_indexes where owner = 'SCOTT' AND INDEX_NAME not like 'SYS%'

Oracle 索引基础

Oracle 索引基础 如果一个表中包含有很多条记录,当对表执行查询时,必须将所有的记录一一取出,以便将每一条记录与查询条件进行比较,然后再返回满足条件的记录。这样进行操作的时间开销和I/O开销都是十分巨大的。这时就可以考虑通过建立索引来减少开销。 简单地说,如果将表看作一本书,索引的作用则类似于书中的目录。在没有目录的情况下,要在书中查找指定的内容必须阅读全书,而有了目录之后,只需要通过目录就可以快速找到包含所需内容的页。类似地,如果要在表中查询指定的记录,在没有索引的情况下,必须遍历整个表,而有了索引之后,只需要在索引中找到符合查询条件的索引字段值,就可以通过保存在索引中的ROWID(相当于页码)快速找到表中对应的记录。 因此,合理地使用索引可以大大降低磁盘的I/O次数,从而提高数据访问性能。假设EMP表中的数据占用了10000了数据块,如果EMPNO列上不存在索引,那么当执行查询操作时需要执行全表扫描,这种操作的I/O次数为10000次;如果EMPNO列上存在索引(假设索引层次为2),那么执行查询时将使用索引进行扫描(I/O次数为4次)。 索引与表一样,不仅需要在数据字典中保存索引的定义,还需要在表空间中为它分配实际的存储空间。当创建索引时,Oracle会自动在用户的默认表空间中或指定的表空间中创建一个索引段,为索引数据提供存储空间。与创建表的情况类以,在创建索引时也可以为它设置存储参数。 为某个表创建的索引不必和该表保存在同一个表空间中。如果将索引和对应的表分别存放在位于不同硬盘上的不同的表空间中,反而能够提高查询的速度。因为Oracle能够并行读取不同硬盘中的数据,这样的查询可以避免产生I/O冲突。 在创建索引时,Oracle首先对将要建立索引的字段进行排序,然后将排序后的字段值和对应记录的ROWID存储在索引段中。例如,假设使用下面的语句为EMP表中的ENAME 字段创建索引: SQL> create index emp_ename on emp (ename); 索引已创建。 Oracle首先在EMP表中按照ENAME字段进行排序,默认为升序排序,然后按照排序后的顺序将ENAME字段值和对应的ROWID逐个保存在索引中。建立索引的字段被称为索此字段,例如ENAME字段即为索引字段。 在索引创建之后,如果执行一条在WHERE子句中引用了ENAME字段的查询。例如:SQL> select ename,hiredate,sal 2 from emp 3 where ename='SMITH'; ENAME HIREDA TE SAL ---------- -------------- --------- SMITH 17-12月-80 960 Oracle将首先对索引中的ENAME字段进行一次快速搜索(因为索引中的ENAME字段已经排序,所以该搜索是非常快的),找到符合条件的ENAME字段值所对应的ROWID,然后再利用ROWID到EMP表中提取相应的记录。这个操作比逐条读取EMP表中未排序的记录要快得多。可以看出,在索引中只保存索引字段的值与相应的ROWID,这种组合称为

Oracle数据库创建索引的几个原则

在Oracle数据库中要合理的创建索引有如下几个要求。 一、根据表的大小来创建索引。 虽然给表创建索引,可以提高查询的效率。但是数据库管理员需要注意的是,索引也需要一定的开销的。为此并不是说给所有的表都创建索引,那么就可以提高数据库的性能。这个认识是错误的。恰恰相反,如果不管三七二十一,给所有的表都创建了索引,那么其反而会给数据库的性能造成负面的影响。因为此时滥用索引的开销可能已经远远大于由此带来的性能方面的收益。所以笔者认为,数据库管理员首先需要做到,为合适的表来建立索引,而不是为所有的表建立索引。 一般来说,不需要为比较小的表创建索引。如在一个ERP系统的数据库中,department表用来存储企业部门的信息。一般企业的部分也就十几个,最多不会超过一百个。这100条记录对于人来说,可能算是比较多了。但是对于计算机来说,这给他塞塞牙缝都还不够。所以,对类似的小表没有必要建立索引。因为即使建立了索引,其性能也不会得到很大的改善。相反索引建立的开销,如维护成本等等,要比这个要大。也就是说,付出的要比得到的多,显然违反常理。 另外,就是对于超大的表,也不一定要建立索引。有些表虽然比较大,记录数量非常的多。但是此时为这个表建立索引并一定的合适。如系统中有一张表,其主要用来保存数据库中的一些变更信息。往往这些信息只给数据库管理员使用。此时为这张表建立索引的话,反而不合适。因为这张表很少用到,只有在出问题的时候才需要查看。其次其即使查看,需要查询的纪录也不会很多,可能就是最近一周的更新记录等等。对于对于一些超大的表,建立索引有时候往往不能够达到预计的效果。而且在打表上建立索引,其索引的开销要比普通的表大的多。那么到底是否给大表建立索引呢?笔者认为,主要是看两个方面的内容。首先是需要关注一下,在这张大表中经常需要查询的记录数量。一般来说,如果经常需要查询的数据不超过10%到15%的话,那就没有必要为其建立索引的必要。因为此时建立索引的开销可能要比性能的改善大的多。这个比例只是一个经验的数据。如果数据库管理员需要得出一个比较精确的结论,那么就需要进行测试分析。即数据库管理员需要测试一下全表扫描的时间,看看其是否比建立索引后的查询时间要长或者短。如果是长的话,则说明有建立索引的必要。但是如果没有的话,则说明还是全表扫描速度来的快。此时也就没有必要建立索引了。 总之,在考虑是否该为表建立索引时,一般来说小表没有建立索引的必要。而对于打表的话,则需要进行实际情况实际分析。简单一点的,可以根据大致的比率来确定。如果要精确一点的,则可以进行全表扫描性能分析,以判断建立索引后是否真的如预期那样改善了数据库性能。 二、根据列的特征来创建索引。

oracle索引类型和使用技巧

1.不同类型索引和适用范围 Oracle提供了大量索引选项。知道在给定条件下使用哪个选项对于一个应用程序的性能来 说非常重要。一个错误的选择可能会引发死锁,并导致数据库性能急剧下降或进程终止。 而如果做出正确的选择,则可以合理使用资源,使那些已经运行了几个小时甚至几天的进 程在几分钟得以完成,这样会使您立刻成为一位英雄。下面就将简单的讨论每个索引选项。 1.1.B树索引 (默认类型) 树索引在Oracle中是一个通用索引。在创建索引时它就是默认的索引类型。B树索引可以是一个列的(简单)索引,也可以是组合/复合(多个列)的索引。B树索引最多可以包括32列。在下图的例子中,B树索引位于雇员表的last_name列上。这个索引的二元高度为3;接 下来,Oracle会穿过两个树枝块(branch block),到达包含有ROWID的树叶块。在每个树枝块中,树枝行包含链中下一个块的ID号。 树叶块包含了索引值、ROWID,以及指向前一个和后一个树叶块的指针。Oracle可以从两个方向遍历这个二叉树。B树索引保存了在索引列上有值的每个数据行的ROWID值。Oracle不会对索引列上包含NULL值的行进行索引。如果索引是多个列的组合索引,而其 中列上包含NULL值,这一行就会处于包含NULL值的索引列中,且将被处理为空(视为NULL)。 技巧:索引列的值都存储在索引中。因此,可以建立一个组合(复合)索引,这些索引可以 直接满足查询,而不用访问表。这就不用从表中检索数据,从而减少了I/O量。 B-tree 特点: 适合与大量的增、删、改(OLTP) 不能用包含OR操作符的查询; 适合高基数的列(唯一值多) 典型的树状结构; 每个结点都是数据块; 大多都是物理上一层、两层或三层不定,逻辑上三层; 叶子块数据是排序的,从左向右递增; 在分支块和根块中放的是索引的范围;

Oracle索引的应用

Oracle索引的应用 在本练习中,将为HR模式中的STUDENT表创建索引,并查看索引的使用情况。 (1)连接到HR模式,使用如下的语句在STUDENT表的SNAME列上创建B树非惟一索引: create index name_index on Student(Sname) tablespace users; (2)在STUDENT的班级信息列上创建位图索引: create bitmap index sclass_index on Student(classid) tablespace users; (3)执行如下的查询语句,并查看Oracle的执行计划。 set autotrace traceonly select * from student where sname='王丽'; (4)根据索引的使用情况,并删除不经常使用的索引。 alter index name_index monitoring usage; select * from v$object_usage where table_name=upper('student'); (5)查看索引的状态,是否存有过多的碎片,当被删除的叶结点过多时,就说明该B 树索引存在过多的碎片,这就需要重建或合并该索引。 analyze index name_index validate structure; select br_pows,br_blks,lf_rows,del_lf_rows from index_stats where name=upper('name_index'); alter index name_index COALESCE DEALLOCATE UNUSED;--合并索引 alter index name_index REBUILD; --在原来的表空间重建索引

oracle索引说明

第一章由浅至深讲解Oracle数据库 B-tree索引B-tree索引结构: B-tree索引: ·索引会随着时间的增加而变的不平衡; ·删除的索引空间不会被重用; ·随着索引层数的增加,索引将会变得无效并需要重建; ·聚簇因子差,索引需要重建; ·为了提高性能,索引需要经常重建; 索引基础 ·一个更新由一个删除和一个插入组成;

·页块由索引条目(row header(2/3B)|length(1B)|indexed data value(nB)|length (1B)|RowID(6B))和相应的rowid组成; ·每个页块包含两个指针分别前面的页块和后面页块; Treedump alter session set events ‘immediate trace name treedump level index_object _id’; ----- begin tree dump branch: 0x424362 4342626 (0: nrow: 2, level: 1) leaf: 0x424363 4342627 (-1: nrow: 540 rrow: 540) leaf: 0x424364 4342628 (0: nrow: 461 rrow: 461) ----- end tree dump 以上dump包含的信息如下: 块类型:branch(分支块);leaf(页块); 块地址:0x424362 4342626; nrow:索引条目的数量; rrow:当前块中的索引条目数量; level:分支块等级(页块隐示为0); Block Dump alter system dump datafile X block X; alter system dump datafile X block min X1 block max X2

Oracle 索引 详解

Oracle 索引详解 https://www.doczj.com/doc/762190878.html,/tianlesoftware/article/details/5347098 一.索引介绍 1.1 索引的创建语法: CREATE UNIUQE | BITMAP INDEX . ON . ( | ASC | DESC, | ASC | DESC,...) TABLESPACE STORAGE LOGGING | NOLOGGING COMPUTE STATISTICS NOCOMPRESS | COMPRESS NOSORT | REVERSE PARTITION | GLOBAL PARTITION 相关说明 1)UNIQUE | BITMAP:指定UNIQUE为唯一值索引,BITMAP为位图索引,省略为B-Tree 索引。 2) | ASC | DESC:可以对多列进行联合索引,当为expression时即“基于函数的索引” 3)TABLESPACE:指定存放索引的表空间(索引和原表不在一个表空间时效率更高) 4)STORAGE:可进一步设置表空间的存储参数 5)LOGGING | NOLOGGING:是否对索引产生重做日志(对大表尽量使用NOLOGGING 来减少占用空间并提高效率) 6)COMPUTE STATISTICS:创建新索引时收集统计信息 7)NOCOMPRESS | COMPRESS:是否使用“键压缩”(使用键压缩可以删除一个键列中出现的重复值) 8)NOSORT | REVERSE:NOSORT表示与表中相同的顺序创建索引,REVERSE表示相

Oracle全文索引技术-使用说明文档解析

[Oracle全文索引技术] 使用说明文档 金联万家(北京)电子支付科技发展有限公司

修改记录 目录 1 前言 (3) 1.1 编写目的 (3) 1.2 名词解释 (3) 1.3 参考资料 (3) 2 oracle全文索引技术 (4) 3 建立全文索引的操作步骤 (4) 3.1 查看用户与角色 (4) 3.2 开启目标用户全文索引权限 (4) 3.3 设置语法分析器Lexer (5) 3.4 建立索引 (5) 3.5 使用索引 (6) 4 全文索引的种类 (6) 5 对多字段建立索引 (6) 6 Oracle全文索引之 - CONTEXT (7) 6.1 函数 CONTAINS 语法 (7) 6.2 全文索引的维护 (7) 6.2.1 同步数据 (8) 6.3 单个中文字查询问题 (9) 7 建立全文索引的完整脚本 (10) 8 附录 (14)

1前言 1.1编写目的 本文档主要说明Oracle全文索引技术的使用与维护,为数据库操作使用人员提供参考维护手册。 1.2名词解释 表 1.术语表 1.3参考资料 表 2.参考资料列表

2oracle全文索引技术 全文检索:是指计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。 【Oracle Text 全文检索】 Oracle一直致力于全文检索技术的研究,当Oracle9i Rlease2发布之时,Oracle数据库的全文检索技术已经非常完美,Oracle Text使Oracle9i具备了强大的文本检索能力和智能化的文本管理能力。Oracle Text是Oracle9i 采用的新名称,在Oracle8/8i中它被称作Oracle interMedia Text,在Oracle8以前它的名称是Oracle ConText Cartridge。使用Oracle9i和Oracle Text,可以方便而有效地利用标准的SQL工具来构建基于文本的新的开发工具或对现有应用程序进行扩展。应用程序开发人员可以在任何使用文本的Oracle数据库应用程序中充分利用Oracle Text搜索,应用范围可以是现有应用程序中可搜索的注释字段,也可是实现涉及多种文档格式和复杂搜索标准的大型文档管理系统。Oracle Text支持Oracle数据库所支持的大多数语言的基本全文搜索功能。 扩展阅读: https://www.doczj.com/doc/762190878.html,/view/663956.htm 3建立全文索引的操作步骤 3.1查看用户与角色 检查数据库中是否有CTXSYS 用户和CTXAPP 角色 如果没有这个用户和角色,意味着你的数据库创建时未安装intermedia功能。你必须修改数据库以安装这项功能。默认安装情况下,ctxsys用户是被锁定的,因此要先启用ctxsys的用户。 -- 锁住用户 ALTER USER ctxsys ACCOUNT LOCK PASSWORD EXPIRE; -- 解锁用户 ALTER USER ctxsys ACCOUNT UNLOCK IDENTIFIED BY ctxsys; 如果没有该用户,则需要打开dbca工具中选择configrue database options,然后选择所有数据库组件安装即可。 3.2开启目标用户全文索引权限 赋权在ctxsys用户下把ctx_ddl的执行权限赋于要使用全文索引的用户,例: GRANT EXECUTE ON ctx_ddl TO username;

Oracle用户名重建索引方法探究 (1)

每个DBA都应该知道数据索引的重要性。特别是管理Oracle的DBA,很多应用项目会涉及到大量的修改删除操作,数据索引是需要周期性的重建的。这里介绍的根据Oracle用户名重建索引的方法可以帮助我们提高查询性能。 更重要的是,它不仅可以提高查询性能,还能增加索引表空间空闲空间大小。在Oracle里大量删除记录后,表和索引里占用的数据块空间并没有释放。重建索引可以释放已删除记录索引占用的数据块空间。 下面是可以按Oracle用户名生成重建索引的SQL脚本: 1.SET ECHO OFF; 2.SET FEEDBACK OFF; 3.SET VERIFY OFF; 4.SET PAGESIZE 0; 5.SET TERMOUT ON; 6.SET HEADING OFF; 7.ACCEPT username CHAR PROMPT 'Enter the index username: '; 8.spool /oracle/rebuild_&username.sql; 9.SELECT 10.'REM +-----------------------------------------------+' || chr(10) || 11.'REM | INDEX NAME : ' || owner || '.' || segment_name 12.|| lpad('|', 33 - (length(owner) + length(segment_name)) ) 13.|| chr(10) || 14.'REM | BYTES : ' || bytes 15.|| lpad ('|', 34-(length(bytes)) ) || chr(10) || 16.'REM | EXTENTS : ' || extents 17.|| lpad ('|', 34-(length(extents)) ) || chr(10) || 18.'REM +-----------------------------------------------+' || chr(10) || 19.'ALTER INDEX ' || owner || '.' || segment_name || chr(10) || 20.'REBUILD ' || chr(10) || 21.'TABLESPACE ' || tablespace_name || chr(10) || 22.'STORAGE ( ' || chr(10) || 23.' INITIAL ' || initial_extent || chr(10) || 24.' NEXT ' || next_extent || chr(10) || 25.' MINEXTENTS ' || min_extents || chr(10) || 26.' MAXEXTENTS ' || max_extents || chr(10) || 27.' PCTINCREASE ' || pct_increase || chr(10) || 28.');' || chr(10) || chr(10) 29.FROM dba_segments 30.WHERE segment_type = 'INDEX' 31.AND owner='&username' 32.ORDER BY owner, bytes DESC; 33.spool off; 如果你用的是Windows系统,想改变输出文件的存放目录,修改spool后面的路径成:

相关主题
文本预览
相关文档 最新文档