Oracle索引

  • 一、索引介绍
    • 1、什么是索引?
    • 2、使用索引的目的
  • 二、索引的分类及结构
    • 1、逻辑上:
    • 2、物理上:
  • 三、各种索引详解
    • 1、 B树索引
      • (1)特点:
      • (2)技巧:
    • 2、位图索引
      • (1)特点:
      • (2)技巧:
    • 3、 反向索引
      • (1)特点:
      • (2)技巧:
    • 4、HASH索引
      • (1)特点:
    • 5、函数索引
    • 6、分区索引和全局索引
    • 7、域索引 Domain
  • 四、怎样建立索引
    • 1、普通索引
    • 2、唯一索引
    • 3、位图索引
    • 4、组合索引
    • 5、基于函数索引
    • 6、反向键索引
    • 7.重置索引
    • 8.删除索引
  • 五、索引失效细节
    • 1.使用不等于操作符(<>, !=)
    • 2.使用 is null 或 is not null
    • 3.使用函数
    • 4.比较不匹配的数据类型
    • 5.使用like子句
    • 6.使用in
    • 7.如果能不用到排序,则尽量避免排序

一、索引介绍

1、什么是索引?

  索引是建立在表的一列或多个列上的辅助对象,目的是加快访问表中的数据;Oracle存储索引的数据结构是B树,位图索引也是如此,只不过是叶子节点不同B数索引;索引由根节点、分支节点和叶子节点组成,上级索引块包含下级索引块的索引数据,叶节点包含索引数据和确定行实际位置的rowid。

2、使用索引的目的

  当查询返回的记录数排序表<40%非排序表 <7%且表的碎片较多(频繁增加、删除)时可以加快查询速度减少I/O操作消除磁盘排序

二、索引的分类及结构

1、逻辑上:

Single column/Concatenated 单行索引/多行索引
Unique/NonUnique 唯一索引/非唯一索引

2、物理上:

B-tree B树索引
Bitmap 位图索引
REVERSE 反向索引
HASHHASH索引
Function-based基于函数的索引
Partitioned/NonPartitioned 分区索引/非分区索引
Domain 域索引

三、各种索引详解

1、 B树索引

  Oracle数据库中最常见的索引类型是b-tree索引,也就是B-树索引,以其同名的计算科学结构命名。CREATE INDEX语句时,默认就是在创建b-tree索引。没有特别规定可用于任何情况。

(1)特点:

  适合与大量的增、删、改(OLTP)
  不能用包含OR操作符的查询;
  适合高基数的列(唯一值多)
  典型的树状结构;
  每个结点都是数据块;
  大多都是物理上一层、两层或三层不定,逻辑上三层;
  叶子块数据是排序的,从左向右递增;
  在分支块和根块中放的是索引的范围;

(2)技巧:

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

2、位图索引

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

(1)特点:

  适合与决策支持系统;
  做UPDATE代价非常高;
  非常适合OR操作符的查询;
  基数比较少的时候才能建位图索引;

(2)技巧:

  对于有较低基数的列需要使用位图索引。性别列就是这样一个例子,它有两个可能值:男或女(基数仅为2)。位图对于低基数(少量的不同值)列来说非常快,这是因为索引的尺寸相对于B树索引来说小了很多。因为这些索引是低基数的B树索引,所以非常小,因此您可以经常检索表中超过半数的行,并且仍使用位图索引。
  当大多数条目不会向位图添加新的值时,位图索引在批处理(单用户)操作中加载表(插入操作)方面通常要比B树做得好。当多个会话同时向表中插入行时不应该使用位图索引,在大多数事务处理应用程序中都会发生这种情况。
  在一个查询中合并多个位图索引后,可以使性能显著提高。位图索引使用固定长度的数据类型要比可变长度的数据类型好。较大尺寸的块也会提高对位图索引的存储和读取性能。

3、 反向索引

  这个索引不常见,但是特定情况特别有效,比如一个varchar(5)位字段(员工编号)含值
(10001,10002,10033,10005,10016…)
这种情况默认索引分布过于密集,不能利用好服务器的并行
但是反向之后10001,20001,33001,50001,61001就有了一个很好的分布,能高效的利用好并行运算。

(1)特点:

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

(2)技巧:

  如果您的磁盘容量有限,同时还要执行大量的有序载入,就可以使用反转键索引。

4、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对于一些包含有序值的静态数据非常有效。

(1)特点:

  可以在表中创建基于函数的索引。如果没有基于函数的索引,任何在列上执行了函数的查询都不能使用这个列的索引。例如,下面的查询就不能使用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语句的执行就会花费越多的时间。

5、函数索引

  可以在表中创建基于函数的索引。如果没有基于函数的索引,任何在列上执行了函数的查询都不能使用这个列的索引。例如,下面的查询就不能使用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语句的执行就会花费越多的时间。

6、分区索引和全局索引

  分区索引就是简单地把一个索引分成多个片断。通过把一个索引分成多个片断,可以访问更小的片断(也更快),并且可以把这些片断分别存放在不同的磁盘驱动器上(避免I/O问题)。B树和位图索引都可以被分区,而HASH索引不可以被分区。可以有好几种分区方法:表被分区而索引未被分区;表未被分区而索引被分区;表和索引都被分区。不管采用哪种方法,都必须使用基于成本的优化器。分区能够提供更多可以提高性能和可维护性的可能性
有两种类型的分区索引:本地分区索引和全局分区索引。每个类型都有两个子类型,有前缀索引和无前缀索引。表各列上的索引可以有各种类型索引的组合。如果使用了位图索引,就必须是本地索引。把索引分区最主要的原因是可以减少所需读取的索引的大小,另外把分区放在不同的表空间中可以提高分区的可用性和可靠性。
  在使用分区后的表和索引时,Oracle还支持并行查询和并行DML。这样就可以同时执行多个进程,从而加快处理这条语句。
  可以使用与表相同的分区键和范围界限来对本地索引分区。每个本地索引的分区只包含了它所关联的表分区的键和ROWID。本地索引可以是B树或位图索引。如果是B树索引,它可以是唯一或不唯一的索引。
  这种类型的索引支持分区独立性,这就意味着对于单独的分区,可以进行增加、截取、删除、分割、脱机等处理,而不用同时删除或重建索引。Oracle自动维护这些本地索引。本地索引分区还可以被单独重建,而其他分区不会受到影响。

7、域索引 Domain

  域索引实际为用户自定义索引,域索引主要对存储在数据库中的媒体,图像数据进行索引,这些数据在oracle中基本上以BLOB类型存储,不同的应用存储格式也不同,oracle不可能提供某一种现成的算法对这些数据进行索引,为了能够对这些类型数据快速访问,oracle提供了现成的接口函数,用户可以针对自己的数据格式实现这些接口函数,以达到对这些数据的快速访问。

四、怎样建立索引

CREATE UNIQUE | 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 | NOLOGGINGCOMPUTE STATISTICSNOCOMPRESS | COMPRESS<nn>NOSORT | REVERSEPARTITION | GLOBAL PARTITION<partition_setting>

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

1、普通索引

create index index_text_txt on test(txt);

2、唯一索引

create unique index <index_name> on <table_name>(<coiumn_name>);

3、位图索引

create bitmap index <index_name> on <table_name>(<column_name>)

4、组合索引

create index <index_name> on <table_name>(<column_name1><column_name2>)

5、基于函数索引

create index <index_name> on <table_name>(column_name) reverse;
create index <index_name> on <table_name>(upper(column_name))

6、反向键索引

create index <index_name> on <table_name>(column_name) reverse;

7.重置索引

alter index <index_name> rebuild;

8.删除索引

drop index <index_name>

五、索引失效细节

1.使用不等于操作符(<>, !=)

  下面这种情况,即使在列dept_id有一个索引,查询语句仍然执行一次全表扫描

select * from dept where staff_num <> 1000;

  但是开发中的确需要这样的查询,难道没有解决问题的办法了吗?
  有!
  通过把用 or 语法替代不等号进行查询,就可以使用索引,以避免全表扫描:上面的语句改成下面这样的,就可以使用索引了。

select * from dept shere staff_num < 1000 or dept_id > 1000;

2.使用 is null 或 is not null

  使用 is null 或is nuo null也会限制索引的使用,因为数据库并没有定义null值。如果被索引的列中有很多null,就不会使用这个索引(除非索引是一个位图索引,关于位图索引,会在以后的blog文章里做详细解释)。在sql语句中使用null会造成很多麻烦。
解决这个问题的办法就是:建表时把需要索引的列定义为非空(not null)

3.使用函数

  如果没有使用基于函数的索引,那么where子句中对存在索引的列使用函数时,会使优化器忽略掉这些索引。下面的查询就不会使用索引:

select * from staff where trunc(birthdate) = '01-MAY-82';

  但是把函数应用在条件上,索引是可以生效的,把上面的语句改成下面的语句,就可以通过索引进行查找。

select * from staff where birthdate < (to_date('01-MAY-82') + 0.9999);

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

  比较不匹配的数据类型也是难于发现的性能问题之一。下面的例子中,dept_id是一个varchar2型的字段,在这个字段上有索引,但是下面的语句会执行全表扫描。

select * from dept where dept_id = 900198;

  这是因为oracle会自动把where子句转换成to_number(dept_id)=900198,就是3所说的情况,这样就限制了索引的使用。把SQL语句改为如下形式就可以使用索引

select * from dept where dept_id = '900198';

5.使用like子句

  使用like子句查询时,数据需要把所有的记录都遍历来进行判断,索引不能发挥作用,这种情况也要尽量避免。
Like 的字符串中第一个字符如果是‘%’则用不到索引
Column1 like ‘aaa%’ 是可以的
Column1 like ‘%aaa%’用不到

6.使用in

  尽管In写法要比exists简单一些,exists一般来说性能要比In要高的多
用In还是用Exists的时机,当in的集合比较小的时候,或者用Exists无法用到选择性高的索引的时候,用In要好,否则就要用Exists
例:

select count(*) from person_info where xb in (select xb_id from dic_sex);
Select count(*) from n_acntbasic a where shbxdjm =:a and exists(select 1 from person_info where pid=a.pid and …);Select * from person_info where zjhm=3101….;将会对person_info全表扫描
Select * from person_info where zjhm =‘3101…’才能用到索引

  假定TEST表的dt字段是date类型的并且对dt建了索引。
  如果要查‘20041010’一天的数据.下面的方法用不到索引

Select * from test where to_char(dt,’yyyymmdd’) =‘20041010’;
而select * from test where dt >=to_date(‘20041010’,’yyyymmdd’) and dt < to_date(‘20041010’,’yyyymmdd’) + 1 将会用到索引。

7.如果能不用到排序,则尽量避免排序

  用到排序的情况有集合操作。Union ,minus ,intersect等,注:union all 是不排序的。Order by、Group by、Distinct、In 有时候也会用到排序,确实要排序的时候也尽量要排序小数据量,尽量让排序在内存中执行,有文章说,内存排序的速度是硬盘排序的1万倍。

Oracle索引详解相关推荐

  1. Oracle索引详解(索引的原理,创建索引,删除索引,修改索引等)

    Oracle索引详解 一.索引概述 Oracle作为关系型数据库,用户查找数据与行的物理位置无关,表中的每一行均用一个ROWID来标识,当Oracle数据库中存储海量的记录时,就意味着有大量的ROWI ...

  2. Oracle 索引 详解 - 索引分类

    二. 索引分类 Oracle提供了大量索引选项.知道在给定条件下使用哪个选项对于一个应用程序的性能来说非常重要.一个错误的选择可能会引发死锁,并导致数据库性能急剧下降或进程终止.而如果做出正确的选择, ...

  3. Oracle索引 详解

    一.索引介绍 1.1 索引的创建语法: CREATE UNIUQE | BITMAP INDEX <schema>.<index_name> ON <schema> ...

  4. 转: Oracle 索引详解

    一. 索引介绍 1.1 索引的创建语法          CREATE UNIUQE | BITMAP INDEX <schema>.<index_name>          ...

  5. oracle spool文件名+系统时间,Oracle Spool详解

    转自:http://blog.sina.com.cn/s/blog_6bccf0360101hzsh.html 1.spool的作用是什么? spool的作用可以用一句话来描述:在sqlplus中用来 ...

  6. oracle数据库中索值,Oracle数据库中的索引详解

    Oracle数据库中的索引详解以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 一 ROWID的概念 存储了row在数据文 ...

  7. oracle分区表编程,Oracle分区表详解

    当前位置:我的异常网» 编程 » Oracle分区表详解 Oracle分区表详解 www.myexceptions.net  网友分享于:2013-10-28  浏览:25次 Oracle分区表详解 ...

  8. oracle有哪两种内存结构,Oracle体系结构详解(物理构造,内存结构和逻辑结构)...

    当前位置:我的异常网» 数据库 » Oracle体系结构详解(物理构造,内存结构和逻辑结构 Oracle体系结构详解(物理构造,内存结构和逻辑结构) www.myexceptions.net  网友分 ...

  9. oracle里面asm的作用,Oracle ASM 详解

    Oracle ASM 详解 ASM:Automatic Storage Management, 是Oracle 主推的一种面向Oracle的存储解决方案, ASM 和 RDBMS 非常相似,ASM 也 ...

  10. Oracle 存储过程详解(上)

    目录 一.存储过程与存储函数的定义 二.创建 / 执行存储过程所需的权限 1.resource权限 2.create.execute procedure权限 三.创建 / 执行存储过程 四.变量与参数 ...

最新文章

  1. 华东理工大学计算机应用基础,最新华东理工大学计算机应用基础网上作业及全部答案...
  2. Oracle 索引 详解 - 索引分类
  3. PL/SQL程序设计 第一章 PL/SQL 程序设计简介
  4. 考oracle ocm,Oracle数据库OCM考试系列教程与总结_OCM考试实验笔记
  5. HDU - 1151 Air Raid(最小路径覆盖-二分图最大匹配)
  6. java json特殊字符处理_java json字符串传递给 js 时 特殊字符转义错误 研究
  7. Java架构师必备框架技能核心笔记,工作感悟
  8. 2022年百度新能源汽车行业洞察
  9. 怎样把照片中的头像扶正_一个男人的微信头像,往往暴露了“人品”,你是哪一种?...
  10. HTML5+CSS3从入门到精通
  11. dts同步常见问题_家庭影院十大常见故障解决办法
  12. 米奇emoji_三星S9的AR Emoji迎新角色:迪士尼的米奇和米妮
  13. 领导干部信息管理系统某省实践案例
  14. 【干货】PS 如何快速抠图示例
  15. python中group是啥_python中group和groups函数的区别
  16. 漫画 |《帝都程序猿十二时辰》
  17. 统一网关Gateway-搭建网关服务
  18. kmeans以及kmeans++聚类生成anchors
  19. Unity3d 实现落叶飘效果
  20. mac 环境下 登陆失败问题Access denied for user ‘root‘@‘localhost‘ (using password: YES)

热门文章

  1. 鸿鹄论坛oracle资料,鸿鹄论坛_HCNA-Storage (H13-611)题库 v4.0.pdf
  2. PyTorch-07 卷积神经网络(什么是卷积、卷积神经网络、池化层、Batch normalization、经典卷积网络、深度残差网络 ResNet、nn.Module、数据增强)
  3. 缘 一篇文章 里面有很多喜欢的句子,日后阅读慢慢标记
  4. oracle可以只装客户端吗,我想在linux下只装oracle客户端行吗?怎么装?
  5. 软件工程师必读技术书籍推荐
  6. c++ 度分秒相互转化
  7. 土方计算软件FastTFT V15.1.0更新说明(支持AutoCAD2020平台)
  8. cfe刷机教程 斐讯k3_斐讯K3刷机教程官改V2.1D或者其它版本教程
  9. PB如何配置数据源及自带的PB系统
  10. 指南-AT应用指南-AT指令指南-音频播放和TTS