Oracle索引总结(三)- Oracle索引种类之反向索引

一 反向索引

1.1 反向索引的定义

  • 反向索引作为B-tree索引的一个分支,主要是在创建索引时,针对索引列的索引键值进行字节反转,进而实现分散存放到不同叶子节点块的目的。

1.2 反向索引针对的问题

  • 使用传统的B-tree索引,当索引的列是按顺序产生时,相应的索引键值会基本分布在同一个叶块中。当用户对该列进行操作时,难免会发生索引块的争用。
  • 使用反向索引,将索引列的键值进行反转,实现顺序的键值分散到不同的叶块中,从而减少索引块的争用。
  • 例如:键值1001、1002、1003,反转后1001、2001、3001,进而分散到不用的叶子节点块中。

1.3 反向索引应用场景

  • 索引块成为热点块
  • rac环境
    • rac环境下中多节点访问访问数据呈现密集且集中的特点,索引热块的产生较高。
    • 在范围检索不高的rac环境中使用反向索引可有效提高性能。

1.4 反向索引的优点与缺点

  • 优点:降低索引叶子块的争用问题,提升系统性能。
  • 缺点:对于范围检索,例如:between,>,<时,反向索引无法引用,进而导致全表扫面的产生,降低系统性能。

1.5 反向索引示例说明

  • -- 创建两张相同结构的表,内部结构及数据均引用scott用户下的emp表SQL> select count(*) from test01;
    
      COUNT(*)
    ----------
            14
    
    SQL> select count(*) from test02;
    
      COUNT(*)
    ----------
            14
    
    --针对表TEST01的empno列,添加B-tree索引
    SQL> create index PK_TEST01 on TEST01(EMPNO);
    Index created.
    
    --针对表TEST02的empno列,添加反向索引
    SQL> create index PK_REV_TEST02 on TEST02(EMPNO) REVERSE;
    Index created.
    
    --验证上面的索引,NORMAL/REV表明为反向索引
    SQL> select TABLE_NAME,INDEX_NAME,INDEX_TYPE from user_indexes where INDEX_NAME like ‘%TEST%‘;
    
    TABLE_NAME           INDEX_NAME           INDEX_TYPE
    -------------------- -------------------- --------------------
    TEST01               PK_TEST01            NORMAL
    TEST02               PK_REV_TEST02        NORMAL/REV
    
    --打开会话追踪
    SQL> set autotrace traceonly
    
    --相同条件查询,观察两表的执行计划
    SQL> select * from TEST01 where empno=7369;
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 515586510
    
    -----------------------------------------------------------------------------------------
    | Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
    -----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |           |     1 |    87 |     2   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| TEST01    |     1 |    87 |     2   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | PK_TEST01 |     1 |       |     1   (0)| 00:00:01 |
    -----------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("EMPNO"=7369)
    
    Note
    -----
       - dynamic sampling used for this statement (level=2)
    
    Statistics
    ----------------------------------------------------------
            152  recursive calls
              0  db block gets
             23  consistent gets
              0  physical reads
              0  redo size
           1025  bytes sent via SQL*Net to client
            523  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
              1  rows processed
    
    SQL> select * from TEST02 where empno=7369;
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 1053012716
    
    ---------------------------------------------------------------------------------------------
    | Id  | Operation                   | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
    ---------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |               |     1 |    87 |     2   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| TEST02        |     1 |    87 |     2   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | PK_REV_TEST02 |     1 |       |     1   (0)| 00:00:01 |
    ---------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("EMPNO"=7369)
    
    Note
    -----
       - dynamic sampling used for this statement (level=2)
    
    Statistics
    ----------------------------------------------------------
            148  recursive calls
              0  db block gets
             21  consistent gets
              0  physical reads
              0  redo size
           1025  bytes sent via SQL*Net to client
            523  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
              1  rows processed
    
    -- 相同范围条件查询,观察两表的执行计划
    SQL> select * from TEST01 where empno between 7350 and 7500;
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 515586510
    
    -----------------------------------------------------------------------------------------
    | Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
    -----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT            |           |     2 |   174 |     2   (0)| 00:00:01 |
    |   1 |  TABLE ACCESS BY INDEX ROWID| TEST01    |     2 |   174 |     2   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN          | PK_TEST01 |     2 |       |     1   (0)| 00:00:01 |
    -----------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("EMPNO">=7350 AND "EMPNO"<=7500)
    
    Note
    -----
       - dynamic sampling used for this statement (level=2)
    
    Statistics
    ----------------------------------------------------------
              9  recursive calls
              0  db block gets
             10  consistent gets
              0  physical reads
              0  redo size
           1120  bytes sent via SQL*Net to client
            523  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
              2  rows processed
    
    SQL> select * from TEST02 where empno between 7350 and 7500;
    
    Execution Plan
    ----------------------------------------------------------
    Plan hash value: 3294238222
    
    ----------------------------------------------------------------------------
    | Id  | Operation         | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |        |     2 |   174 |     3   (0)| 00:00:01 |
    |*  1 |  TABLE ACCESS FULL| TEST02 |     2 |   174 |     3   (0)| 00:00:01 |
    ----------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter("EMPNO">=7350 AND "EMPNO"<=7500)
    
    Note
    -----
       - dynamic sampling used for this statement (level=2)
    
    Statistics
    ----------------------------------------------------------
              5  recursive calls
              0  db block gets
              8  consistent gets0  redo size
           1112  bytes sent via SQL*Net to client
            523  bytes received via SQL*Net from client
              2  SQL*Net roundtrips to/from client
              0  sorts (memory)
              0  sorts (disk)
              2  rows processed

    通过上面的示例可以看到,当使用between条件进行范围查询时,采用反向索引的表,并没有使用索引,而是采用了全表扫面的方式进行检索。

时间: 2024-08-18 00:12:22

Oracle索引总结(三)- Oracle索引种类之反向索引的相关文章

CM开发日志(四) - Solr 反向索引

什么是反向索引?(很多文章也称为倒排索引) 索引技术主要有以下3种: 反向索引,后缀数组和签名文件.其中, 反向索引技术在当前大多数的信息检索系统中得到了广泛的应用, 它对于关键词的搜索非常有效, 在lucene中也是使用的这种技术.后缀数组技术在短语查询中具有很快的速度, 但是这样的数据结构在构造和维护时都比较复杂一些.签名文件技术在20世纪80年代比较流行, 但是后来反向索引技术逐渐超越了它. 反向索引是目前搜索引擎公司对搜索引擎最常用的存储方式, 也是搜索引擎的核心内容, 反向索引源于实际

【Oracle】第三章索引视图序列

第三章索引视图序列 序列是用来生成唯一,连续的整数的数据库对象.序列是用来自动生成主键或唯一键的值. CREATE SEQUENCE  sequence_name START WITH  integer INCREMENT BY  integer MAXVALUE   integer|nomaxvalue MINVALUE    integer|nominvalue CYCLE|NOCYCLE CACHE  integer|nocache; START WITH     指要生成的第一个序列号,

Oracle索引总结(四)- Oracle索引种类之位图索引

位图索引 1.1 位图索引概述 位图索引通过位图向量,表示索引键值在表中的分布. 适用于没有大量更新操作的对象,如:OLAP数据库. 对于存在大量更新操作的索引列,不适用位图索引.因此对于OLTP并不适用. 更新位图向量时,相应位图涉及的所有数据行会被锁定,无法针对这些数据行的该索引列进行DML操作. 1.2 位图索引结构的说明 与B-tree索引的联系及区别如下: 与B-tree索引的联系:位图索引使用B-tree形式组成. 与B-tree索引的区别:位图索引的一个索引键值对应一个叶子节点.(

Oracle非关键文件恢复,redo、临时文件、索引文件、密码文件

增量备份的应用在recovery阶段,不再restore阶段 了解数据库设置表: SQL>desc database_properties Name                                      Null?    Type ----------------------------------------- -------- ---------------------------- PROPERTY_NAME                             NO

Oracle笔记(十三) 视图、同义词、索引

Oracle笔记(十三) 视图.同义词.索引 一.视图 在之前所学习过的所有的SQL语法之中,查询操作是最麻烦的,如果程序开发人员将大量的精力都浪费在查询的编写上,则肯定影响代码的工作进度,所以一个好的数据库设计人员,除了根据业务的操作设计出数据表之外,还需要为用户提供若干个视图,而每一个视图包装了一条条复杂的SQL语句,视图的创建语法如下: CREATE [OR REPLACE] VIEW 视图名称 AS 子查询; 范例:创建一张视图 CREATE VIEW myview AS SELECT

Oracle事务和对象上集(视图、索引)

一.Oracle事务·事务的含义:事务是业务上的一个逻辑单元,为了保证数据的所有操作要么全部完成,要么全部失败.1.事务的开始是从一条SQL语句开始,结束于下面的几种情况:1)显示提交:输入commit指令,事务完成提交2)显示回滚:输入rollback指令,未提交的事务丢掉,回滚到事务开始时的状态.3)DDL语句:即create.drop等语句,这些语句会使事务自动隐式提交4)结束程序:输入exit退出数据库,则自动提交事务:或者意外终止.出现程序崩溃,则事务自动回滚.2.事务的特点-ACID

Oracle性能分析6:数据访问方式之索引扫描

这节将介绍各种索引扫描方式,在了解了各种索引扫描方式的特点后,你就可以判断你的执行计划中使用的扫描方式是否正确,并可以针对获取的信息作出改进. 索引唯一扫描 在下面的场景中使用相等条件时,数据库使用索引唯一扫描. 1)查询条件中包含唯一索引中的所有列时: 2)查询条件使用主键约束列时. 下面是一个实际的例子,在表historyalarm中创建如下唯一索引: create unique index idx_historyalarm$queryid on historyalarm(queryid)

Oracle性能分析5:数据访问方式之索引结构和扫描方式介绍

上篇文章讲述了全扫描,这篇文章将介绍索引的结构和扫描方式,在后面将开始讲述每一种扫描方式. 当Oracle通过索引检索具体的一列或多列的列值时,就会执行索引扫描.首先我们来看看索引节点包含的数据. 索引节点包含的数据 索引可以被创建在表的单列或者多列上,索引中包含了这些列的值.rowid和一些其它信息,我们关心的只有列值和rowid.由于索引带有列值,应此如果你的SQL语句只涉及到索引的列,那么Oracle就只从索引本身检索列值,而不需要访问表.如果查询涉及到索引列以外的列,Oracle就需要使

Oracle 11g新特性invisible index(不可见的索引)

如果一张表上有十几个索引,你有什么感受?显然会拖慢增.删.改的速度,不要指望开发人员能建好索引.我的处理方法是先监控很长的一段时间,看哪些索引没有用到,然后删除.但删除以后,如果发现某一天有用,那又要重新建,如果是大表,那就有些麻烦.现在11g提供一个新特性,不可见索引,可以建索引设置为不可见索引,CBO在评估执行计划的时候会忽略它,如果需要的时候,设置回来即可. 还有一种用途,你在调试一条SQL语句,要建一个索引测试,而你不想影响其他的会话,用不可见索引正是时候. SQL> drop tabl