精华内容
下载资源
问答
  • oracle-索引

    千次阅读 2017-07-17 07:50:30
    (1)是一种快速查询表中内容的机制,类似于新华字典的目录 (2)运用在表中某个/些字段上,但存储时,独立于表之外   2.为什么要用索引 (1)通过指针加速Oracle服务器的查询速度 (2)通过rowid快速定位数据的...

    索引

    1.什么是索引【Index】

    1)是一种快速查询表中内容的机制,类似于新华字典的目录

    2)运用在表中某个/些字段上,但存储时,独立于表之外

     

    2.为什么要用索引

    1)通过指针加速Oracle服务器的查询速度

    2)通过rowid快速定位数据的方法,减少磁盘I/O

         rowid是oracle中唯一确定每张表不同记录的唯一身份证

     

    3.rowid的特点

    1)位于每个表中,但表面上看不见,例如:desc emp是看不见的

    2)只有在select中,显示写出rowid,方可看见

    3)它与每个表绑定在一起,表亡,该表的rowid亡,二张表rownum可以相同,但rowid必须是唯一的

    4)rowid是18位大小写加数字混杂体,唯一表代该条记录在DBF文件中的位置

    5)rowid可以参与=/like比较时,用''单引号将rowid的值包起来,且区分大小写

    6)rowid是联系表与DBF文件的桥梁

     

    4.索引的特点

    1)索引一旦建立, Oracle管理系统会对其进行自动维护, 而且由Oracle管理系统决定何时使用索引

    2)用户不用在查询语句中指定使用哪个索引

    3)在定义primary key或unique约束后系统自动在相应的列上创建索引

    4)用户也能按自己的需求,对指定单个字段或多个字段,添加索引

     

    5.什么时候【要】创建索引

    1)表经常进行 SELECT 操作

    2)表很大(记录超多),记录内容分布范围很广

    3)列名经常在 WHERE 子句或连接条件中出现

     注意:符合上述某一条要求,都可创建索引,创建索引是一个优化问题,同样也是一个策略问题

           

    6.什么时候【不要】创建索引

    1)表经常进行 INSERT/UPDATE/DELETE 操作

    2)表很小(记录超少)

    3)列名不经常作为连接条件或出现在 WHERE 子句中

    同上注意

     

    7.emp表的empno单个字段,创建索引emp_empno_idx,叫单列索引,create index 索引名 on 表名(字段,...)

    create index emp_empno_idx

    on emp(empno);

     

    8.emp表的ename,job多个字段,创建索引emp_ename_job_idx,多列索引/联合索引

    create index emp_ename_job

    on emp(ename,job);

    如果在where中只出现job不使用索引

    如果在where中只出现ename使用索引

    我们提倡同时出现ename和job

     

    注意:索引创建后,只有查询表有关,和其它(insert/update/delete)无关,解决速度问题

     

    9.删除emp_empno_idx和emp_ename_job_idx索引,drop index 索引名

    drop index emp_empno_idx;

    drop index emp_ename_job_idx;

    展开全文
  • Oracle索引创建和使用

    万次阅读 2016-09-07 13:38:39
    OLTP系统索引创建 创建索引的作用 1、通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 2、可以大大加快数据的检索速度,这也是创建索引的最主要的原因。 3、可以加速表和表之间的连接,特别是在实现...
    

    OLTP系统索引创建

    创建索引的作用

    1通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
    2可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
    3可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
    4使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。

    5通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能

    如何选择索引列

    一、应该建索引列的特点

    1在经常需要搜索的列上,可以加快搜索的速度;
    2在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;
    3在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度;

    4在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围    是连续的;
    5在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;
    6在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。

    二、不应该建索引列的特点

    1对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而 降低了系统的维护速度和增大了空间需求。
    2
    对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。
    3
    对于那些定义为blob数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。
    4
    当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。(数据量庞大,考虑创建分区索引)

    索引的创建语法

    CREATEUNIUQE | BITMAP INDEX <schema>.<index_name>
    ON <schema>.<table_name>
    (<column_name> | <expression> ASC | DESC,
    <column_name> | <expression> ASC | DESC,...)
    TABLESPACE <tablespace_name>
    STORAGE <storage_settings>
    LOGGING | NOLOGGING
    COMPUTE STATISTICS
    NOCOMPRESS | COMPRESS<nn>
    NOSORT | REVERSE
    PARTITION | GLOBAL PARTITION<partition_setting>


    相关说明
    1
    UNIQUE | BITMAP:指定 UNIQUE为唯一值索引, BITMAP为位图索引,省略为 B-Tree索引。
    2
    <column_name> |<expression> ASC | DESC:可以对多列进行联合索引,当为
    expression
    时即基于函数的索引
    3 TABLESPACE:指定存放索引的表空间(索引和原表不在一个表空间时效率更高)
    4
    STORAGE:可进一步设置表空间的存储参数
    5 LOGGING | NOLOGGING:是否对索引产生重做日志(对大表尽量使用 NOLOGGING
    来减少占用空间并提高效率)
    6
    COMPUTESTATISTICS:创建新索引时收集统计信息
    7 NOCOMPRESS | COMPRESS<nn>:是否使用键压缩‖(使用键压缩可以删除一个键列
    中出现的重复值)
    8
    NOSORT | REVERSE NOSORT 表示与表中相同的顺序创建索引, REVERSE表示相

    反顺序存储索引值
    9 PARTITION | NOPARTITION:可以在分区表和未分区表上对创建的索引进行分区

    索引使用误区

    限制索引

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

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

      下面的查询即使在cust_rating列有一个索引,查询语句仍然执行一次全表扫描。
        select cust_Id,cust_name from customers wherecust_rating<> 'aa';
      
    把上面的语句改成如下的查询语句,这样,在采用基于规则的优化器而不是基于代价的优化器(更智能)时,将会使用索引。
       select cust_Id,cust_name fromcustomers where cust_rating<'aa' orcust_rating > 'aa';

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

    2、 使用 IS NULL IS NOT NULL

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

    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);

    4、比较不匹配的数据类型

    也是比较难于发现的性能问题之一。 注意下面查询的例子,account_number是一个VARCHAR2类型, account_number字段上有索引。
    下面的语句将执行全表扫描:
    select bank_name,address,city,state,zip from banks whereaccount_number = 990354;
    Oracle
    可以自动把 where子句变成to_number(account_number)=990354,这样就限
    制了索引的使用,改成下面的查询就可以使用索引:
    select bank_name,address,city,state,zip from banks where account_number='990354';
    特别注意: 不匹配的数据类型之间比较会让
    Oracle自动限制索引的使用,即便对这个查询执行ExplainPlan也不能让您明白为什么做了一次全表扫描。

    5、查询索引

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

    6、 组合索引

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

    索引分类

    Oracle提供了大量索引选项。知道在给定条件下使用哪个选项对于一个应用程序的性能来说非常重要。一个错误的选择可能会引发死锁,并导致数据库性能急剧下降或进程终止。而如果做出正确的选择,则可以合理使用资源,使那些已经运行了几个小时甚至几天的进程在几分钟得以完成,下面就将简单的讨论每个索引选项。
    在这里讨论如下的索引类型:
       B树索引(默认类型)
       
    位图索引
       HASH索引
       
    索引组织表索引
       
    反转键
    (reverse key)索引
       
    基于函数的索引
       
    分区索引
    (本地和全局索引)
        位图连接索引

    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操作符的查询;
       
    适合高基数的列(唯一值多)
       
    典型的树状结构;
       
    每个结点都是数据块;
       
    大多都是物理上一层、两层或三层不定,逻辑上三层;
       
    叶子块数据是排序的,从左向右递增;
       
    在分支块和根块中放的是索引的范围;

    位图索引

    位图索引非常适合于决策支持系统(Decision Support SystemDSS)和数据仓
    库,它们不应该用于通过事务处理应用程序访问的表。它们可以使用较少到中等基数(不同值的数量)的列访问非常大的表。尽管位图索引最多可达30个列,但通常它们都只用于少量的列。
    例如,您的表可能包含一个称为Sex的列,它有两个可能值:男和女。这个基数只为2,如果用户频繁地根据Sex列的值查询该表,这就是位图索引的基列。当一个表内包含了多个位图索引时,您可以体会到位图索引的真正威力。如果有多个可用的位图索引,Oracle就可以合并从每个位图索引得到的结果集,快速删除不必要的数据。
    Bitmapt特点:
       适合与决策支持系统;
       
    UPDATE代价非常高;

    非常适合 OR操作符的查询;
    基数比较少的时候才能建位图索引;


    技巧:对于有较低基数的列需要使用位图索引。性别列就是这样一个例子,它有
    两个可能值:男或女
    (基数仅为2)位图对于低基数(少量的不同值)列来说非常
    ,这是因为索引的尺寸相对于B树索引来说小了很多。因为这些索引是低基
    数的
    B 树索引,所以非常小,因此您可以经常检索表中超过半数的行,并且仍
    使用位图索引。
    当大多数条目不会向位图添加新的值时,位图索引在批处理
    (单用户)操作中
    加载表
    (插入操作)方面通常要比B树做得好。当多个会话同时向表中插入行时不
    应该使用位图索引,在大多数事务处理应用程序中都会发生这种情况。
    示例
    下面来看一个示例表
    PARTICIPANT,该表包含了来自个人的调查数据。列
    Age_CodeIncome_LevelEducation_LevelMarital_Status都包括了各自
    的位图索引。 下图显示了每个直方图中的数据平衡情况,以及对访问每个位图索
    引的查询的执行路径。图中的执行路径显示了有多少个位图索引被合并,可以看
    出性能得到了显著的提高。

     


    如上图图所示,优化器依次使用4个单独的位图索引,这些索引的列在
    WHERE子句中被引用。每个位图记录指针(例如01),用于指示表中的哪些行包含位图中的已知值。有了这些信息后,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环境中使用位图索引

    HASH索引

    使用HASH索引必须要使用HASH集群。建立一个集群或HASH集群的同时,也就定义了一个集群键。这个键告诉Oracle如何在集群上存储表。在存储数据时,所有与这个集群键相关的行都被存储在一个数据库块上。
    如果数据都存储在同一个数据库块上, 并且将
    HASH索引作为WHERE子句中的确切匹配,Oracle就可以通过执行一个HASH函数和I/O来访问数据——而通过使用一个二元高度为4B树索引来访问数据,则需要在检索数据时使用4I/O
    如下图所示,其中的查询是一个等价查询,用于匹配
    HASH列和确切的值。
    Oracle可以快速使用该值,基于HASH函数确定行的物理存储位置。
    HASH索引可能是访问数据库中数据的最快方法,但它也有自身的缺点。集群键上不同值的数目必须在创建HASH集群之前就要知道。需要在创建HASH集群的时候指定这个值。低估了集群键的不同值的数字可能会造成集群的冲突(两个集群的键值拥有相同的HASH)这种冲突是非常消耗资源的。冲突会造成用来存储额外行的缓冲溢出,然后造成额外的I/O。如果不同HASH值的数目已经被低估,您就必须在重建这个集群之后改变这个值。
    ALTER CLUSTER命令不能改变HASH键的数目。HASH集群还可能浪费
    空间。如果无法确定需要多少空间来维护某个集群键上的所有行,就可能造成空
    间的浪费。如果不能为集群的未来增长分配好附加的空间HASH集群可能就
    是最好的选择
    如果应用程序经常在集群表上进行全表扫描HASH集群可能也
    不是最好的选择。由于需要为未来的增长分配好集群的剩余空间量,全表扫描可
    能非常消耗资源。
    在实现
    HASH集群之前一定要小心。您需要全面地观察应用程序,保证在实
    现这个选项之前已经了解关于表和数据的大量信息。
    通常,HASH对于一些包含
    有序值的静态数据非常有效。
    技巧:
    HASH索引在有限制条件(需要指定一个确定的值而不是一个值范围)的情
    况下非常有用

    索引组织表

    索引组织表会把表的存储结构改成B树结构,以表的主键进行排序。这种特
    殊的表和其他类型的表一样,可以在表上执行所有的
    DMLDDL语句。由于
    表的特殊结构,
    ROWID并没有被关联到表的行上。
    对于一些涉及精确匹配和范围搜索的语句,索引组织表提供了一种基于键的
    快速数据访问机制。
    基于主键值的UPDATEDELETE语句的性能也同样得以
    提高,
    这是因为行在物理上有序。由于键列的值在表和索引中都没有重复,存储所需要的空间也随之减少。
    如果不会频繁地根据主键列查询数据,则需要在索引组织表中的其他列上创
    建二级索引。不会频繁根据主键查询表的应用程序不会了解到使用索引组织表的
    全部优点。
    对于总是通过对主键的精确匹配或范围扫描进行访问的表,就需要考
    虑使用索引组织表。

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

    反转键索引

    当载入一些有序数据时,索引肯定会碰到与I/O相关的一些瓶颈。在数据载
    入期间,某部分索引和磁盘肯定会比其他部分使用频繁得多。为了解决这个问题,
    可以把索引表空间存放在能够把
    文件物理分割在多个磁盘上的磁盘体系结构上
    为了解决这个问题,
    Oracle还提供了一种反转键索引的方法。如果数据以反
    转键索引存储,这些数据的值就会与原先存储的数值相反。这样,数据
    1234
    12351236就被存储成432153216321结果就是索引会为每次新插入
    的行更新不同的索引块。
    技巧:
    如果您的磁盘容量有限,同时还要执行大量的有序载入,就可以使用
    反转键索引。

    不可以将反转键索引与位图索引或索引组织表结合使用。 因为不能对位图索
    引和索引组织表进行反转键处理。

    基于函数的索引

    可以在表中创建基于函数的索引。如果没有基于函数的索引,任何在列上执
    行了函数的查询都不能使用这个列的索引。例如,下面的查询就不能使用
    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语句的性能带来何种影
    响?

     

    基于函数的索引非常有用,但在实现时必须小心。在表上创建的索引越多,
    INSERTUPDATEDELETE语句的执行就会花费越多的时间。
    注意:对于优化器所使用的基于函数的索引来说,必须把初始参数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!!!

    分区索引

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

    每个类型都有两个子类型,有前缀索引和无前缀索引。表各列上的索引可以有各种类型索引的组合。
    如果使用了位图索引,就必须是本地索引。把索引分区最主要的原因是可以减少
    所需读取的索引的大小,另外把分区放在不同的表空间中可以提高分区的可用性
    和可靠性。在使用分区后的表和索引时,
    Oracle还支持并行查询和并行DML。这样就可以同时执行多个进程,从而加快处理这条语句。

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

    可以使用与表相同的分区键和范围界限来对本地索引分区。每个本地索引的
    分区只包含了它所关联的表分区的键和
    ROWID。本地索引可以是B树或位图索
    引。如果是
    B树索引,它可以是唯一或不唯一的索引。
    这种类型的索引支持分区独立性,这就意味着对于单独的分区,可以进行增
    加、截取、删除、分割、脱机等处理,而不用同时删除或重建索引。
    Oracle
    动维护这些本地索引。
    本地索引分区还可以被单独重建,而其他分区不会受到影
    响。
    1) 有前缀的索引
    有前缀的索引包含了来自分区键的键,并把它们作为索引的前导。例如,让
    我们再次回顾
    participant表。在创建该表后,使用survey_idsurvey_date
    两个列进行范围分区,然后在
    survey_id列上建立一个有前缀的本地索引,如下图所示。这个索引的所有分区都被等价划分,就是说索引的分区都使用表的相同
    范围界限来创建。

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

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

     

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

     

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

    全局分区索引

    全局分区索引在一个索引分区中包含来自多个表分区的键。一个全局分区索
    引的分区键是分区表中不同的或指定一个范围的值。在创建全局分区索引时,必
    须定义分区键的范围和值。
    全局索引只能是B树索引Oracle在默认情况下不会维护全局分区索引。
    如果一个分区被截取、增加、分割、删除等,就必须重建全局分区索引
    ,除非在
    修改表时指定
    ALTER TABLE命令的UPDATE GLOBAL INDEXES子句。
    2) 有前缀的索引
    通常,全局有前缀索引在底层表中没有经过对等分区。没有什么因素能限制
    索引的对等分区,但
    Oracle在生成查询计划或执行分区维护操作时,并不会充
    分利用对等分区。如果索引被对等分区,就必须把它创建为一个本地索引,这样
    Oracle可以维护这个索引,并使用它来删除不必要的分区,如下图所示。在该
    图的
    3个索引分区中,每个分区都包含指向多个表分区中行的索引条目。

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

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

    位图连接索引

    位图连接索引是基于两个表的连接的位图索引,在数据仓库环境中使用这种索引改进连接维度表和事实表的查询的性能。创建位图连接索引时,标准方法是
    连接索引中常用的维度表和事实表。当用户在一次查询中结合查询事实表和维度
    表时,就不需要执行连接,因为在位图连接索引中已经有可用的连接结果。通过
    压缩位图连接索引中的
    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
    子句查询
    SALESCUSTOMER表,优化器就可以使用位图连接索引快速返回匹配连接
    条件和
    Customer_Name条件的行。
    位图连接索引的使用一般会受到限制:
    1) 只可以索引维度表中的列。
    2) 用于连接的列必须是维度表中的主键或唯一约束;如果是复合主键,则
    必须使用连接中的每一列。
    3) 不可以对索引组织表创建位图连接索引,并且适用于常规位图索引的限
    制也适用于位图连接索引。
     

     

    注意:以上总结是对oracle数据库中索引创建的一些知识的介绍和关键点。需要读懂理解之后结合系统业务情况合理创建索引,以求达到预期性能。

    本文部分内容摘自《Oracle超详细讲解.pdf》

    展开全文
  • Oracle-索引

    2017-03-01 17:07:23
    索引创建语法(Oracle):  CREATE [ UNIUQE | BITMAP ] INDEX .  ON .  ( | ASC | DESC,  | ASC | DESC,... )  TABLESPACE  STORAGE  LOGGING | NOLOGGING  COMPUTE STATISTICS  
    索引的创建语法(Oracle):
    
        CREATE [ UNIUQE | BITMAP ] INDEX <schema>.<index_name>
        ON <schema>.<table_name>
        ( <column_name> | <expression> ASC | DESC,
          <column_name> | <expression> ASC | DESC,... )
        TABLESPACE <tablespace_name>
        STORAGE <storage_settings>
        LOGGING | NOLOGGING
        COMPUTE STATISTICS
        NOCOMPRESS | COMPRESS<nn>
        NOSORT | REVERSE
        PARTITION | GLOBAL PARTITION <partition_setting> ;
    说明:
        1)UNIQUE | BITMAP:指定UNIQUE为唯一值索引,BITMAP为位图索引,省略为B-Tree索引。
        2)<column_name> | <expression> ASC | DESC:可以对多列进行联合索引,当为expression时即“基于函数的索引”
            column 基表中的列名,一个索引最多有16列,long列、long raw列不能建索引列
    DESC、ASC 缺省为ASC即升序排序
        3)TABLESPACE:指定存放索引的表空间(索引和原表不在一个表空间时效率更高)
        4)STORAGE:可进一步设置表空间的存储参数
        5)LOGGING | NOLOGGING:是否对索引产生重做日志(对大表尽量使用NOLOGGING来减少占用空间并提高效率)
        6)COMPUTE STATISTICS:创建新索引时收集统计信息
        7)NOCOMPRESS | COMPRESS<nn>:是否使用“键压缩”(使用键压缩可以删除一个键列中出现的重复值)
        8)NOSORT | REVERSE:NOSORT表示与表中相同的顺序创建索引,REVERSE表示相反顺序存储索引值
        9)PARTITION | NOPARTITION:可以在分区表和未分区表上对创建的索引进行分区

    数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用B树及其变种B+树。
    在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。
    为表设置索引要付出代价的:一是增加了数据库的存储空间,二是在插入和修改数据时要花费较多的时间(因为索引也要随之变动)。

    创建索引可以大大提高系统的性能。
    第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
    第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
    第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
    第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
    第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。 

    增加索引也有许多不利的方面:
    第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
    第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。
    第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。

    索引是建立在数据库表中的某些列的上面。在创建索引的时候,应该考虑在哪些列上可以创建索引,在哪些列上不能创建索引。
    一般来说,应该在这些列上创建索引:
        在经常需要搜索的列上,可以加快搜索的速度;
        在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;
        在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度;
        在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的;
        在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;
        在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。

    同样,对于有些列不应该创建索引。一般来说,不应该创建索引的的这些列具有下列特点:
        第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。
        第二,对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。
        第三,对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。
        第四,当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。

    限制索引
        限制索引是一些没有经验的开发人员经常犯的错误之一。在SQL中有很多陷阱会使一些索引无法使用。下面讨论一些常见的问题:
        a.使用不等于操作符(<>、!=)    
            下面的查询即使在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条件,就可以使用索引,以避免全表扫描。
       b.使用IS NULL 或IS NOT NULL
            使用IS NULL 或IS NOT NULL同样会限制索引的使用。因为NULL值并没有被定义。在SQL语句中使用NULL会有很多的麻烦。
            因此建议开发人员在建表时,把需要索引的列设成NOT NULL。如果被索引的列在某些行中存在NULL值,就不会使用这个索引(除非索引是一个位图索引,关于位图索引在稍后在详细讨论)。
       c.使用函数
            如果不使用基于函数的索引,那么在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);
        d.比较不匹配的数据类型      
            也是比较难于发现的性能问题之一。 注意下面查询的例子,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也不能让您明白为什么做了一次“全表扫描”。

    常见的索引类型:
    唯一索引 
        唯一索引是不允许其中任何两行具有相同索引值的索引。
        当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。数据库还可能防止添加将在表中创建重复键值的新数据。
        例如,如果在employee表中职员的姓(lname)上创建了唯一索引,则任何两个员工都不能同姓。
        当建立Primary Key(主键)或者Unique constraint(唯一约束)时,唯一索引将被自动建立
        语法:CREATE UNIQUE INDEX index ON table (column);
    主键索引
        数据库表经常有一列或列组合,其值唯一标识表中的每一行。该列称为表的主键。
        在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。当在查询中使用主键索引时,它还允许对数据的快速访问。
    聚集索引(Oracle没有直接的,要用索引组织表来变通使用)
        在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。
        如果某索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。
        聚集索引存储记录是物理上连续存在,非聚集索引是逻辑上的连续。
        聚集索引对于那些经常要搜索范围值的列特别有效。使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻。
        例如,如果应用程序执行 的一个查询经常检索某一日期范围内的记录,则使用聚集索引可以迅速找到包含开始日期的行,然后检索表中所有相邻的行,直到到达结束日期。
        这样有助于提高此类查询的性能。
        同样,如果对从表中检索的数据进行排序时经常要用到某一列,则可以将该表在该列上聚集(物理排序),避免每次查询该列时都进行排序,从而节省成本。
        聚集索引就像汉语词典里按拼音查找,结果是连续的。
        非聚集索引就像汉语词典里按部首查找,结果是不连续的。
        聚集索引优点:
            1、以最快的速度缩小查询范围。
            2、以最快的速度进行字段排序。
        聚集索引使用场合:
            1、此列包含有限数目的不同值。
            2、查询的结果返回一个区间的值。
            3、查询的结果返回某值相同的大量结果集。
        非聚集索引优点:
            1、非聚集索引比聚集索引层次多。
            2、添加记录不会引起数据顺序的重组。
        非聚集索引使用场合:
            1、此列包含了大量数目不同的值。
            2、查询的结束返回的是少量的结果集。


    Oracle支持的其它索引类型:
    B树索引(默认类型)
        CREATE  INDEX 索引名 on 表名(列名) ;
        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操作符的查询;
        适合高基数的列(唯一值多)
        典型的树状结构;
        每个结点都是数据块;
        大多都是物理上一层、两层或三层不定,逻辑上三层;
        叶子块数据是排序的,从左向右递增;
        在分支块和根块中放的是索引的范围;

    位图索引
        位图索引非常适合于决策支持系统(Decision Support System,DSS)和数据仓库,它们不应该用于通过事务处理应用程序访问的表。
        它们可以使用较少到中等基数(不同值的数量)的列访问非常大的表。尽管位图索引最多可达30个列,但通常它们都只用于少量的列。
        例如,您的表可能包含一个称为Sex的列,它有两个可能值:男和女。这个基数只为2,如果用户频繁地根据Sex列的值查询该表,这就是位图索引的基列。
        当一个表内包含了多个位图索引时,您可以体会到位图索引的真正威力。如果有多个可用的位图索引,Oracle就可以合并从每个位图索引得到的结果集,快速删除不必要的数据。
        
        Bitmapt 特点:
        适合与决策支持系统;
        做UPDATE代价非常高;
        非常适合OR操作符的查询;
        基数比较少的时候才能建位图索引;
        技巧:对于有较低基数的列需要使用位图索引。性别列就是这样一个例子,它有两个可能值:男或女(基数仅为2)。
        位图对于低基数(少量的不同值)列来说非常快,这是因为索引的尺寸相对于B树索引来说小了很多。
        因为这些索引是低基数的B树索引,所以非常小,因此您可以经常检索表中超过半数的行,并且仍使用位图索引。
      
        当大多数条目不会向位图添加新的值时,位图索引在批处理(单用户)操作中加载表(插入操作)方面通常要比B树做得好。
        当多个会话同时向表中插入行时不应该使用位图索引,在大多数事务处理应用程序中都会发生这种情况。

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

        技巧:如果要查询位图索引列表,可以在USER _INDEXES视图中查询index_type列。
              建议不要在一些联机事务处理(OLTP)应用程序中使用位图索引。
     B树索引的索引值中包含ROWID,这样Oracle就可以在行级别上锁定索引。
     位图索引存储为压缩的索引值,其中包含了一定范围的ROWID,因此Oracle必须针对一个给定值锁定所有范围内的ROWID。
     这种锁定类型可能在某些DML语句中造成死锁。SELECT语句不会受到这种锁定问题的影响。

        位图索引的使用限制:
        基于规则的优化器不会考虑位图索引。
        当执行ALTER TABLE语句并修改包含有位图索引的列时,会使位图索引失效。
        位图索引不包含任何列数据,并且不能用于任何类型的完整性检查。
        位图索引不能被声明为唯一索引。
        位图索引的最大长度为30。
        
        技巧:不要在繁重的OLTP环境中使用位图索引

    HASH索引
        hash partitioned index
        使用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索引在有限制条件(需要指定一个确定的值而不是一个值范围)的情况下非常有用。

    组合(concatented)索引
        当两个或多个列经常一起出现在where条件中时,则在这些列上同时创建组合索引
        组合索引中列的顺序是任意的,也无需相邻。但是建议将最频繁访问的列放在列表的最前面

    位图索引
        列中有非常多的重复的值时候。例如某列保存了 “性别”信息。
        Where 条件中包含了很多OR操作符。
        较少的update操作,因为要相应的跟新所有的bitmap
        结构:位图索引使用位图作为键值,对于表中的每一数据行位图包含了TRUE(1)、FALSE(0)、或NULL值。
        优点:位图以一种压缩格式存放,因此占用的磁盘空间比标准索引要小得多;
        语法:CREATE BITMAP INDEX index ON table (column[, column]...);
        例:create table bitmaptable as select * from indextable where owner in('SYS','PUBLIC');


    基于函数的索引
        在WHERE条件语句中包含函数或者表达式时
        函数包括:算数表达式、PL/SQL函数、程序包函数、SQL函数、用户自定义函数。
        语法:CREATE INDEX index ON table (FUNCTION(column));
        例:必须要分析表,并且 query_rewrite_enabled=TRUE
            或者使用提示/*+ INDEX(ic_index)*/
        
        可以在表中创建基于函数的索引。如果没有基于函数的索引,任何在列上执行了函数的查询都不能使用这个列的索引。例如,下面的查询就不能使用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!!!

    反向键索引( reverse key index ):这也是 B* 树索引,只不过键中的字节会 “ 反转 “ 。
        比如索引值是一个自动增长的列:
        利用反向键索引,如果索引中填充的是递增的值,索引条目在索引中可以得到更均匀的分布。
        例如,如果使用一个序列来生成主键,这个序列将生成诸如 987500 、 987501 、 987502 等值。
        这些值是顺序的,所以倘若使用一 个传统的 B* 树索引,这些值就可能放在同一个右侧块上,这就加剧了对这一块的竞争。
        利用反向键, Oracl e则会逻辑地对 205789 、 105789 、 005789 等建立索引。 
        Oracle 将数据放在索引中之前,将先把所存储数据的字节反转,
        这样原来可能在索引中相邻放置的值在字节反转之后就会相距很远。通过反转字节,对索引的插入就会分布到多个块上。
        多个用户对集中在少数块上的索引行进行修改,容易引起资源的争用,比如对数据块的等待。此时建立反向索引。
        创建示例:
        create table T_ORDER ( ORDER_ID NUMBER(10) not null, CLIENT VARCHAR2(60),ADDRESS VARCHAR2(100),ORDER_DATE CHAR(8));
        create unique index IDX_ORDER_ID on T_ORDER ( ORDER_ID ASC) reverse;
        alter table T_ORDER add constraint PK_ORDER primary key (ORDER_ID) using index IDX_ORDER_ID;
        要保证创建IDX_ORDER_ID的SQL语句在创建PK_ORDER主键的SQL语句之前,因为主键需要引用到这个反向键索引。
      由于主键列的数据是唯一的,所以为IDX_ORDER_ID加上unique限定,使其成为唯一型的索引。


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

    索引组织表(IOT)
        将表中的数据按照索 引的结构存储在索引中,提高查询速度。
        牺牲插入更新的性能,换取查询 性能。通常用于数据仓库,提供大量的查询,极少的插入修改工作。
        必须指定主键。插入数据时,会根据主键列进行B树索引排序,写入磁盘。
        索引组织表会把表的存储结构改成B树结构,以表的主键进行排序。这种特殊的表和其他类型的表一样,可以在表上执行所有的DML和DDL语句。由于表的特殊结构,ROWID并没有被关联到表的行上。

        对于一些涉及精确匹配和范围搜索的语句,索引组织表提供了一种基于键的快速数据访问机制。基于主键值的UPDATE和DELETE语句的性能也同样得以提高,这是因为行在物理上有序。
        由于键列的值在表和索引中都没有重复,存储所需要的空间也随之减少。
        如果不会频繁地根据主键列查询数据,则需要在索引组织表中的其他列上创建二级索引。不会频繁根据主键查询表的应用程序不会了解到使用索引组织表的全部优点。
        对于总是通过对主键的精确匹配或范围扫描进行访问的表,就需要考虑使用索引组织表。
        
        技巧:可以在索引组织表上建立二级索引。

    键压缩索引
        比如表landscp的数据如下:
        site          feature      job
        Britten Park, Rose Bed 1,  Prune
        Britten Park, Rose Bed 1,  Mulch
        Britten Park, Rose Bed 1,  Spray
        Britten Park, Shrub Bed 1, Mulch
        Britten Park, Shrub Bed 1, Weed
        Britten Park, Shrub Bed 1, Hoe
        ……
        查询时,以上3列均在where条件中同时出现,所以建立基于以上3列的组合索引。但是发现重复值很多,所以考虑压缩特性。
        Create index zip_idx on landscp(site, feature, job) compress 2;
        将索引项分成前缀(prefix)和后缀(postfix)两部分。前两项被放置到前缀部分。
        Prefix 0: Britten Park, Rose Bed 1
        Prefix 1: Britten Park, Shrub Bed 1
        实际所以的结构为:
        0 Prune
        0 Mulch
        0 Spray
        1 Mulch
        1 Weed
        1 Hoe
        特点:组合索引的前缀部分具 有非选择性时,考虑使用压缩。减少I/O,增加性能。

    分区索引
        簇: A cluster is a group of tables that share the same data blocks because they share common columns and are often used together.
            集群是一组表共享相同的数据块,因为他们有共同的列和通常一起使用。

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

        有两种类型的分区索引:本地分区索引和全局分区索引。每个类型都有两个子类型,有前缀索引和无前缀索引。
        表各列上的索引可以有各种类型索引的组合。如果使用了位图索引,就必须是本地索引。
        把索引分区最主要的原因是可以减少所需读取的索引的大小,另外把分区放在不同的表空间中可以提高分区的可用性和可靠性。
        在使用分区后的表和索引时,Oracle还支持并行查询和并行DML。这样就可以同时执行多个进程,从而加快处理这条语句。

        A> 本地分区索引(通常使用的索引)
        可以使用与表相同的分区键和范围界限来对本地索引分区。每个本地索引的分区只包含了它所关联的表分区的键和ROWID。
        本地索引可以是B树或位图索引。如果是B树索引,它可以是唯一或不唯一的索引。
        这种类型的索引支持分区独立性,这就意味着对于单独的分区,可以进行增加、截取、删除、分割、脱机等处理,而不用同时删除或重建索引。
        Oracle自动维护这些本地索引。本地索引分区还可以被单独重建,而其他分区不会受到影响。
        A.a> 有前缀的索引
        有前缀的索引包含了来自分区键的键,并把它们作为索引的前导。这个索引的所有分区都被等价划分,就是说索引的分区都使用表的相同范围界限来创建。
        技巧:本地的有前缀索引可以让Oracle快速剔除一些不必要的分区。也就是说没有包含WHERE条件子句中任何值的分区将不会被访问,这样也提高了语句的性能。
        A.b>无前缀的索引
        无前缀的索引并没有把分区键的前导列作为索引的前导列。
        如果要把无前缀的索引设为唯一索引,这个索引就必须包含分区键的子集。

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

        B>全局分区索引
        全局分区索引在一个索引分区中包含来自多个表分区的键。一个全局分区索引的分区键是分区表中不同的或指定一个范围的值。在创建全局分区索引时,必须定义分区键的范围和值。全局索引只能是B树索引。Oracle在默认情况下不会维护全局分区索引。如果一个分区被截取、增加、分割、删除等,就必须重建全局分区索引,除非在修改表时指定ALTER TABLE命令的UPDATE GLOBAL INDEXES子句。
        B.a>有前缀的索引
        通常,全局有前缀索引在底层表中没有经过对等分区。没有什么因素能限制索引的对等分区,但Oracle在生成查询计划或执行分区维护操作时,并不会充分利用对等分区。如果索引被对等分区,就必须把它创建为一个本地索引,这样Oracle可以维护这个索引,并使用它来删除不必要的分区,如下图所示。在该图的3个索引分区中,每个分区都包含指向多个表分区中行的索引条目。
        技巧:如果一个全局索引将被对等分区,就必须把它创建为一个本地索引,这样Oracle可以维护这个索引,并使用它来删除不必要的分区。
        B.b>无前缀的索引
        Oracle不支持无前缀的全局索引。

    位图连接索引
        位图连接索引是基于两个表的连接的位图索引,在数据仓库环境中使用这种索引改进连接维度表和事实表的查询的性能。创建位图连接索引时,标准方法是连接索引中常用的维度表和事实表。当用户在一次查询中结合查询事实表和维度表时,就不需要执行连接,因为在位图连接索引中已经有可用的连接结果。通过压缩位图连接索引中的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 ROWID
        通过每个行的ROWID,索引Oracle提供了访问单行数据的能力。ROWID其实就是直接指向单独行的线路图。如果想检查重复值或是其他对ROWID本身的引用,可以在任何表中使用和指定rowid列。

    查询索引
        查询DBA_INDEXES视图可得到表中所有索引的列表,注意只能通过USER_INDEXES的方法来检索模式(schema)的索引。访问USER_IND_COLUMNS视图可得到一个给定表中被索引的特定列。
        下面的查询可显示索引类型。
        SQL> select index_name, index_type from user_indexes;
             B树索引作为NORMAL列出;而位图索引的类型值为BITMAP。

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

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

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

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

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

    局部性原理与磁盘预读
        由于存储介质的特性,磁盘本身存取就比主存慢很多,再加上机械运动耗费,磁盘的存取速度往往是主存的几百分分之一,因此为了提高效率,要尽量减少磁盘I/O。
        为了达到这个目的,磁盘往往不是严格按需读取,而是每次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存。
        这样做的理论依据是计算机科学中著名的局部性原理:当一个数据被用到时,其附近的数据也通常会马上被使用。程序运行期间所需要的数据通常比较集中。
        由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此对于具有局部性的程序来说,预读可以提高I/O效率。
        预读的长度一般为页(page)的整倍数。页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和磁盘存储区分割为连续的大小相等的块,每个存储块称为一页(在许多操作系统中,页得大小通常为4k),主存和磁盘以页为单位交换数据。
        当程序要读取的数据不在主存中时,会触发一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,然后异常返回,程序继续运行。

    B-/+Tree索引的性能分析
        到这里终于可以分析B-/+Tree索引的性能了。
        上文说过一般使用磁盘I/O次数评价索引结构的优劣。先从B-Tree分析,根据B-Tree的定义,可知检索一次最多需要访问h个节点。数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。为了达到这个目的,在实际实现B-Tree还需要使用如下技巧:
        每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。
        B-Tree中一次检索最多需要h-1次I/O(根节点常驻内存),渐进复杂度为O(h)=O(logdN)。一般实际应用中,出度d是非常大的数字,通常超过100,因此h非常小(通常不超过3)。
        而红黑树这种结构,h明显要深的多。由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性,所以红黑树的I/O渐进复杂度也为O(h),效率明显比B-Tree差很多。
        综上所述,用B-Tree作为索引结构效率是非常高的。

    应该花时间学习B-树和B+树数据结构
    =============================================================================================================
    1)B树
        B树中每个节点包含了键值和键值对于的数据对象存放地址指针,所以成功搜索一个对象可以不用到达树的叶节点。
        成功搜索包括节点内搜索和沿某一路径的搜索,成功搜索时间取决于关键码所在的层次以及节点内关键码的数量。
        在B树中查找给定关键字的方法是:首先把根结点取来,在根结点所包含的关键字K1,…,kj查找给定的关键字(可用顺序查找或二分查找法),若找到等于给定值的关键字,则查找成功;否则,一定可以确定要查的关键字在某个Ki或Ki+1之间,于是取Pi所指的下一层索引节点块继续查找,直到找到,或指针Pi为空时查找失败。

    2)B+树
        B+树非叶节点中存放的关键码并不指示数据对象的地址指针,非也节点只是索引部分。
        所有的叶节点在同一层上,包含了全部关键码和相应数据对象的存放地址指针,且叶节点按关键码从小到大顺序链接。
        如果实际数据对象按加入的顺序存储而不是按关键码次数存储的话,叶节点的索引必须是稠密索引,若实际数据存储按关键码次序存放的话,叶节点索引时稀疏索引。
        B+树有2个头指针,一个是树的根节点,一个是最小关键码的叶节点。
        所以 B+树有两种搜索方法:
        一种是按叶节点自己拉起的链表顺序搜索。
        一种是从根节点开始搜索,和B树类似,不过如果非叶节点的关键码等于给定值,搜索并不停止,而是继续沿右指针,一直查到叶节点上的关键码。所以无论搜索是否成功,都将走完树的所有层。
        B+ 树中,数据对象的插入和删除仅在叶节点上进行。

    这两种处理索引的数据结构的不同之处:
        a,B树中同一键值不会出现多次,并且它有可能出现在叶结点,也有可能出现在非叶结点中。而B+树的键一定会出现在叶结点中,并且有可能在非叶结点中也有可能重复出现,以维持B+树的平衡。
        b,因为B树键位置不定,且在整个树结构中只出现一次,虽然可以节省存储空间,但使得在插入、删除操作复杂度明显增加。B+树相比来说是一种较好的折中。
        c,B树的查询效率与键在树中的位置有关,最大时间复杂度与B+树相同(在叶结点的时候),最小时间复杂度为1(在根结点的时候)。而B+树的时候复杂度对某建成的树是固定的。

    展开全文
  • Oracle索引

    2013-12-27 11:17:42
     索引是由Oracle维护的可...一旦建立索引,在用户表中建立、更改和删除数据库时, Oracle就自动地维护索引创建索引时,下列准则将帮助用户做出决定:  1) 索引应该在SQL语句的"where"或"and...

           索引是由Oracle维护的可选结构,为数据提供快速的访问。准确地判断在什么地方需要使用索引是困难的,使用索引有利于调节检索速度。 当建立一个索引时,必须指定用于跟踪的表名以及一个或多个表列。一旦建立了索引,在用户表中建立、更改和删除数据库时, Oracle就自动地维护索引。创建索引时,下列准则将帮助用户做出决定:

          1) 索引应该在SQL语句的"where"或"and"部分涉及的表列(也称谓词)被建立。假如

      personnel表的"firstname"表列作为查询结果显示,而不是作为谓词部分,则不论其值是什么,该表          列不会被索引。

    2)用户应该索引具有一定范围的表列,索引时有一个大致的原则:如果表中列的值占该表中行的2 0 %以内,这个表列就可以作为候选索引表列。假设一个表有36 000行且表中一个表列的值平均分布(大约每12000行),那么该表列不适合于一个索引。然而,如果同一个表中的其他表列中列值的行在1 0 0 0~1 5 0 0之间(占3 %~4 % ),则该表列可用作索引。

    3)如果在S Q L语句谓词中多个表列被一起连续引用,则应该考虑将这些表列一起放在一个索引内, O r a c l e将维护单个表列的索引(建立在单一表列上)或复合索引(建立在多个表列上)。复合索引称并置索引。

    1、 主关键字的约束

    关系数据库理论指出,在表中能唯一标识表的每个数据行的一个或多个表列是对象的主关键字。由于数据字典中定义的主关键字能确保表中数据行之间的唯一性,因此,在O r a c l e 8 i数据库中建立表索引关键字有助于应用调节。另外,这也减轻了开发者为了实现唯一性检查,而需要各自编程的要求。

      提示使用主关键字索引条目比不使用主关键字索引检索得快。

      假设表 person 把它的 id 表列作为主关键字,用下列代码设置约束:

    alter table person add constraint person_pk primary key (id) using index storage (initial 1m next 1m

    pctincrease 0) tablespace prd_indexes ;

      处理下列S Q L语句时:

    select last_name ,first_name ,salary from person where id = 289 ;

      在查找一个已确定的“ i d”表列值时, Oracle 将直接找到 person_pk。如果其未找到正确的索引条目,Oracle 知道该行不存在。主关键字索引具有下列两个独特之处:

    1.1因为索引是唯一的, 所以 Oracle 知道只有一个条目具有设定值。如果查找到了所期望的条目,则立即终止查找。

      1.2一旦遇到一个大于设定值的条目,索引的顺序搜索可被终止;

    2、 ORDER BY中用索引

      ORDER BY 子句只在两种严格的条件下使用索引.

      ORDER BY中所有的列必须包含在相同的索引中并保持在索引中的排列顺序.

      ORDER BY中所有的列必须定义为非空.

      WHERE子句使用的索引和ORDER BY子句中所使用的索引不能并列.

     例如:

    表DEPT包含以下列:

    DEPT_CODE PK NOT NULL

    DEPT_DESC NOT NULL

    DEPT_TYPE NULL

    非唯一性的索引(DEPT_TYPE)

     

    低效: (索引不被使用)

    SELECT DEPT_CODE FROM DEPT ORDER BY DEPT_TYPE

    EXPLAIN PLAN:SORT ORDER BY TABLE ACCESS FULL

    高效: (使用索引)

    SELECT DEPT_CODE FROM DEPT WHERE DEPT_TYPE > 0

    EXPLAIN PLAN:TABLE ACCESS BY ROWID ON EMP INDEX RANGE SCAN ON DEPT_IDX

    3 避免改变索引列的类型.

      当比较不同数据类型的数据时, ORACLE自动对列进行简单的类型转换.

    假设 EMPNO是一个数值类型的索引列.

    SELECT … FROM EMP WHERE EMPNO = ‘123'

      实际上,经过ORACLE类型转换, 语句转化为:

    SELECT … FROM EMP WHERE EMPNO = TO_NUMBER(‘123')

      幸运的是,类型转换没有发生在索引列上,索引的用途没有被改变.

      现在,假设EMP_TYPE是一个字符类型的索引列.

    SELECT … FROM EMP WHERE EMP_TYPE = 123

      这个语句被ORACLE转换为:

    SELECT … FROM EMP WHERE TO_NUMBER(EMP_TYPE)=123

      因为内部发生的类型转换, 这个索引将不会被用到! 为了避免ORACLE对你的SQL进行隐式的类型转换, 最好把类型转换用显式表现出来. 注意当字符和数值比较时, ORACLE会优先转换数值类型到字符类型.

    4 需要当心的WHERE子句

      某些SELECT 语句中的WHERE子句不使用索引. 这里有一些例子.

      在下面的例子里, ‘!=' 将不使用索引. 记住, 索引只能告诉你什么存在于表中, 而不能告诉你什么不存在于表中.

      不使用索引:

    SELECT ACCOUNT_NAME FROM TRANSACTION WHERE AMOUNT !=0;

      使用索引:

    SELECT ACCOUNT_NAME FROM TRANSACTION WHERE AMOUNT >0;

      下面的例子中, ‘||'是字符连接函数. 就象其他函数那样, 停用了索引. 不使用索引:

    SELECT ACCOUNT_NAME,AMOUNT FROM TRANSACTION

    WHERE ACCOUNT_NAME||ACCOUNT_TYPE='AMEXA';

      使用索引:

    SELECT ACCOUNT_NAME,AMOUNT FROM TRANSACTION

    WHERE ACCOUNT_NAME = ‘AMEX' AND ACCOUNT_TYPE=' A';

      下面的例子中, ‘+'是数学函数. 就象其他数学函数那样, 停用了索引.

      不使用索引:

    SELECT ACCOUNT_NAME, AMOUNT FROM TRANSACTION WHERE AMOUNT + 3000 >5000;

      使用索引:

    SELECT ACCOUNT_NAME, AMOUNT FROM TRANSACTION WHERE AMOUNT > 2000 ;

      下面的例子中,相同的索引列不能互相比较,这将会启用全表扫描.

      不使用索引:

    SELECT ACCOUNT_NAME, AMOUNT FROM TRANSACTION

    WHERE ACCOUNT_NAME = NVL(:ACC_NAME,ACCOUNT_NAME);

      使用索引:

    SELECT ACCOUNT_NAME, AMOUNT FROM TRANSACTION

    WHERE ACCOUNT_NAME LIKE NVL(:ACC_NAME,'%');

      如果一定要对使用函数的列启用索引, ORACLE新的功能: 基于函数的索引(Function-Based Index) 也许是一个较好的

      方案.

    CREATE INDEX EMP_I ON EMP (UPPER(ename)); /*建立基于函数的索引*/

    SELECT * FROM emp WHERE UPPER(ename) = ‘BLACKSNAIL'; /*将使用索引*/

      5 怎样监控无用的索引

      Oracle 9i以上,可以监控索引的使用情况,如果一段时间内没有使用的索引,一般就是无用的索引

      语法为:

      开始监控:alter index index_name monitoring usage;

      检查使用状态:select * from v$object_usage;

      停止监控:alter index index_name nomonitoring usage;

      当然,如果想监控整个用户下的索引,可以采用如下的脚本:

    SELECT 'alter index '||owner||'.'||index_name||' monitoring usage;'

    FROM dba_indexes

    WHERE owner = USER;

     

     

    一.索引介绍 
    1.1 索引的创建语法: 
    CREATE UNIUQE | BITMAP INDEX <schema>.<index_name> 
          ON <schema>.<table_name> 
               (<column_name> | <expression> ASC | DESC, 
                <column_name> | <expression> ASC | DESC,...) 
         TABLESPACE <tablespace_name> 
         STORAGE <storage_settings> 
         LOGGING | NOLOGGING 
        COMPUTE STATISTICS 
         NOCOMPRESS | COMPRESS<nn> 
         NOSORT | REVERSE 
         PARTITION | GLOBAL PARTITION<partition_setting> 
    相关说明 
    1) UNIQUE | BITMAP:指定UNIQUE为唯一值索引,BITMAP为位图索引,省略为B-Tree索引。 
    2)<column_name> | <expression> ASC | DESC:可以对多列进行联合索引,当为expression时即“基于函数的索引” 
    3)TABLESPACE:指定存放索引的表空间(索引和原表不在一个表空间时效率更高) 
    4)STORAGE:可进一步设置表空间的存储参数 
    5)LOGGING | NOLOGGING:是否对索引产生重做日志(对大表尽量使用NOLOGGING来减少占用空间并提高效率) 
    6)COMPUTE STATISTICS:创建新索引时收集统计信息 
    7)NOCOMPRESS | COMPRESS<nn>:是否使用“键压缩”(使用键压缩可以删除一个键列中出现的重复值) 
    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就可以合并从每个位图索引得到的结果集,快速删除不必要的数据。 
    Bitmapt 特点: 
    适合与决策支持系统; 
    做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索引

    2019-03-01 09:17:41
    (1)是一种快速查询表中内容的机制,类似于新华字典的目录 (2)运用在表中某个/些字段上,但存储时,独立于表之外 为什么要用索引 (1)通过指针加速Oracle服务器的查询速度 (2)通过rowid快速定位数据的方法...
  • oracle各种索引介绍

    千次阅读 2015-10-27 16:07:58
    一.... 1.1 索引创建 语法 :  CREATE UNIUQE | BITMAP INDEX .  ON .  ( | ASC | DESC,   | ASC | DESC,...)   TABLESPACE   STORAGE   LOGGING | N
  • Oracle 索引

    2013-01-23 11:04:27
    一.索引介绍 1.1 索引创建语法: CREATE UNIUQE | BITMAP INDEX . ON . ( | ASC | DESC, | ASC | DESC,...) TABLESPACE STORAGE LOGGING | NOLOGGI...
  • oracle索引

    2016-08-17 16:44:35
    转发至 :... Oracle 索引 详解 一. 索引介绍  1.1  索引创建 语法 :   CREATE UNIUQE | BITMAP INDEX .   ON .    ( | ASC | DESC,    
  • oracle索引

    2013-07-01 11:23:00
    一、索引分类 ... 单列索引是基于单列所创建索引 复合(多列)索引(Concatenated): 复合索引是基于两列或者多列所创建索引 唯一索引(Unique): 唯一索引索引列值不能重复的索引。 ...
  • oracle索引

    2013-06-24 21:17:51
    索引介绍 1.1索引创建语法: CREATEUNIUQE|BITMAPINDEX. ON. (|ASC|DESC,|ASC...
  • Oracle 索引 详解

    2014-09-05 16:58:57
    Oracle 索引 详解  一.索引介绍  1.1 索引创建语法:  CREATE UNIUQE | BITMAP INDEX .  ON .  ( | ASC | DESC,  | ASC | DESC,...)  TABLESPACE   STORAGE  ...
  • oracle索引

    2013-04-07 19:55:36
     1.1 索引创建语法:  CREATE UNIUQE | BITMAP INDEX .  ON .  ( | ASC | DESC,  | ASC | DESC,...)  TABLESPACE   STORAGE   LOGGING | NOLOGGING  COMPUTE
  • Oracle索引的使用

    万次阅读 2016-04-22 23:44:53
    一旦建立索引,在用户表中建立、更改和删除数据库时, Oracle就自动地维护索引创建索引时,下列准则将帮助用户做出决定:  1) 索引应该在SQL语句的"where"或"and"部分涉及的表列(也称谓词
  • Oracle 索引详解

    万次阅读 2013-12-11 14:50:29
    Oracle 索引详解 一.索引介绍  1.1 索引创建语法:  CREATE UNIUQE | BITMAP INDEX .  ON .  ( | ASC | DESC,  | ASC | DESC,...)  TABLESPACE   STORAGE   LOGGING | ...
  • 一. 视图 1.1 什么是视图       视图是一种数据库对象,是从一个或者多个数据表或视图中导出...根据创建视图时给定的条件,视图可以是一个数据表的一部分,也可以是多个基表的联合, &n
  • oracle 索引

    2016-08-20 23:49:00
    -普通索引create index 索引名 on 表名 (列名); --单列create index I索引名 on 表名 (列名[, 列名, ....]); --可以有多个列--唯一索引create unique 索引名 on 表名 (列名); --单列create unique I索引名 on 表名 ...
  • oracle 索引压缩

    千次阅读 2015-01-07 15:10:11
    oracle 索引压缩(key compression)是oracle 9i 中引入的一项新特性。该特性可以压缩索引或者索引组织表中的重复键值,从而节省存储空间。非分区的unique 索引和non-unique(至少两列)索引都能够被压缩。bitmap ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,348
精华内容 3,739
关键字:

oracle联合索引创建机制