oracle索引的学习

索引是数据库性能调优非常重要的一个组成部分。当査询数据库内容发现速度异常慢时,DBA首先可能会检査索引,然后考虑一些其他的性能调优的事项。在关系型数据库中索引是可选的,它主要用来进行快速的记录定位。索引虽然是表中可选的组成部分,但是出于对性能的考虑,在规划数据库时就应该考虑创建索引。
索引的数据来自于表,但是它在逻辑上和物理上独立于表,它有自己的存储空间和存储结构,用户可以删除表上的索引,并不会影响索引指向的表。在对表进行插入删除和修改记录时, Oracle会自动维护索引的数据。
一 索引的作用
设想一下图书馆中的图书管理,图书馆一般会创建一个单独的图书目录检索区,指定借书人员可以在哪个分类下的那个书架下的第几层找到所要的图书,相反如果一个接一个书架一路检索过去,估计用户得花很长的时间才能从茫茫书海中找到自己需要的图书。索引的作用与图书馆的图书目录类似,它可以在一个与表独立的位置上存储表中特定字段的已经排序好的数据,在查询数据库时通过检索索引中存储的数据可以快速定位到要查找的记录,索引示意结构如下图:

image.png

在一个表中可以具有一个或者多个索引,在查询数据库数据时,oracle的优化器将会选择最佳的索引来完成数据的检索,为了演示索引的效果,下面将创建两个数据量非常大的表,单表数据量为1937635条数据,一个建立索引,另一个不建立索引(使用set autotrace on;显示执行计划,如执行该命令报错,可参考:http://blog.itpub.net/26148431/viewspace-2140541/)。
1)不建立索引的查询
image.png

image.png

2)建立索引的查询

image.png
image.png

通过示例不难了解(执行计划中TABLE ACCESS FULL表示执行了全表扫描,COST字段指出了查询所消耗的CPU资源,Time指出查询的预估时间,pyhsical reads 表示进行了物理读取操作,读取硬盘是一个缓慢的过程,物理读取会消耗较多的数据库资源)当检索数据库表中的数据时,首先通过对保存了索引的存存储位置进行高速检索,每一个索引键对应了一个行指针ROWD,这个行指针将指向具体的行。
使用索引具有如下的优点:
1.索引使得检索数据的速度大大加快。
2.创建索引时自动添加了唯一性约束,通过使用唯一性索引可以保证数据库表中行数据的唯一性。
3.通过索引可以加快表与表之间的连接,使得在数据库中进行多表连接查询时速度明显增强。
4.使用了索引后,在分组和排序子句进行数据汇总时,可以显著的减少查询中分金组和排序的时间。索引需要在表基础上创建,需要占用额外的物理空间,而且对表进行修改时,比如增、删、改数据的时候,需要动态地进行维护,在进行DML操作时需要占用一定的操作时间。
二 索引的原理
通过图书目录的例子不难想象得到,在图书目录的存储区找到自己想要的图书信息后,最重要的是得获取图书的具体位置信息,然后去根据图书所在的书架位置来获取图书。在 Oracle中,使用 CREATE INDEX语句创建一个索引后, Oracle会将索引放到一个与表独立的存储位置,根据索引类型的不同,它会将索引按照特定的结构进行存储,在存储索引时,不仅会存储被索引的字段信息,它还包含了一个ROWD值,用来指向该索引值,指向表中的具体的记录。索引原理如下图:


image.png

当用户査询一个定义了索引的列时, Oracle会自动进行索引扫描,由于索引的存储结构使用了特定的算法,比如B树索引使用了平衡二又树的存储结构,使得检索的速度大大加快,査找到符合要求的记录后,Oracle将使用 ROWID来定位数据库表中的记录。在Oracle的数据库表中,每张表都会自动具有一个ROWD伪列,这个伪列由 Oracle生成。用来唯一标志一条记录所在物理位置的一个ID号。数据一旦添加到数据库表中,ROWID就生成并且固定了,对数据库表操作的过程中不会被改变。只在表存储位置主变化或者是表空间变化时,由于产生物理位置变化,ROWD的值才会发生改变。用户可以直接在SELECT语句后面使用ROWID伪列来查看ROWID的值。


image.png

ROWID值是由BASE64编码的18位字符串值,它的组成如下所示:
1)第1位到第6位是数据库对象编号。
2)第7位到第9位是相关文件编号。
3)第10位至第15位是块编号。
4)第16位至第18位是行编号。
oracle在构建索引时,出了按结构对要索引的列进行排序和存储外,还会在索引的叶节点上保存行记录的ROWID值,通过ROWID值就可以快速定位到所需的行,从而达到提升性能的目的。
三 索引的分类
Oracle提供了多种索引类型,可以根据索引列的多少进行划分, Oracle具有单列索引和多列索引;如果从索引的列值是否唯一来划分,可以分为唯一性索引和非唯一性索引;如果从功能上来划分,则可以分标准索引、位图索引、索数索引等索引类型。
根据索引列的组成来划分, Oracle中可以创建如下两种类型的索引
1)单列索引,基于单个列所创建的索引,这是最简单的索引创建方式。比如只在empno列上创建的索引,就是单列索引
2)多列索引,又称为复合索引或组合索引,还可以称为拼接索引( concatenatedindex),索引基于数据库表的多个列而创建。
比如索引基于 empno和 ename列而创建,这种索引称为多列索引。

如果按照索引列值的唯一性划分, Oracle中可以创建如下两种类型的索引;
1)唯一性索引:索引列值不能重复的索引,比如一些具有 UNIQUE约東的索引,例如身份证号码,这样的列值不能重复,以该列创建的索引称为唯一性索引。 Oracle不建议人工创建唯一性索引,而是建议在表上定义主键( PRIMARY KEY)约束或唯一性( UNIQUE)约東时,由 Oracle自动在相应的约束列上创建唯一性索引,以符合数据库的完整性约束。
2)非唯一性索引:索引列值可以重复地索引,一殷需要手动使用CREATE INDEX语句进行创建。
注意:唯一性索引和非唯一性索引仅对稍后将要介绍的B树索引有效,B树索引是Oracle默认的索引类型

如果从索引的功能结构上来划分的话, Oracle的索引可以分为如下几种类型:
1)B*树索引, Oracle默认使用的索引,索引按平衡二又树结构组织并存放索引数据,索引可以是单列索引或复合索引、唯一索引或非唯一索引。
2)位图索引,为索引列的每个取值创建一个位图(bit位,而非图片),对表中的每行使用1位(bit,取值为0或1)来表示该行是否包含该位图的索引列的取值。
3)函数索引,索引的取值不直接来自列,而是来自包含有列的函数或表达式,这就是函数索引

B*树索引是 Oracle在默认情况下创建的索引,简称平衡树索引。 Oracle使用基于B-树的变种B*树来实现B树索引,实现的原理与二又查找树相似,它将要索引的列划分为多个范围已排序的列表,通过将键与一行或行范围关联起来,可以对多种类型的查询提供优秀的查询检索性能,包括精确匹配和范围搜索等。举个例子,当对emp表中的 deptno进行B*树索引时, Oracle根据平衡二叉树的结构对 deptno进行了范围的划分。

四 索引创建的策略
由于索引需要创建额外的存储空间,并且在进行 INSERT、 UPDATE和 DELETE操作时, Oracle需要维护索引段中的数据,因此在创建索引之前,必须要制定良好的规划,以避兔造成数据访问的性能低下。
下面总结了一些创建索引的策略:
1)在创建表时指定主键,在创建主键时, Oracle会自动创建唯一性的索引。对相对较小的表避免使用索引,对于小表,使用全表扫描更为合适,比如数据量10多条的表,使用索引反而造成不必要的访问负担。如果需要访问的数据不超过表中总数据量的4%或5%,则需要建立索引,全表扫描适用于请求的数据占全表数据百分比较高的査询,在只需要取出部分数据的场合,使用索引能提供较好的性能。
2)在创建多表连接操作的査询时,对于在连接操作中使用的列建立索引。
3)对在 WHERE子句中频繁使用的列建立索引。
4)对包含在 ORDER BY和 GROUP BY操作中的列或涉及排序的UNON和DISTINCT等其他操作中的列建立索引,由于素引会被排序,因此执行操作的排序要求会显著减少。
5)通常不要在由长字段串组成的列上创建索引。一些需要频繁动态更改的列上,由于Oracle需要维护索引数据,因此会带来较多
的开销,因此理论上不要建立索引。
6)只对有高选择性的表创建索引,即选择几乎没有相同值的表建立索引。
7)不要在一个表中创建大量的索引,在一个表上尽量创建较少数目的索引
8)当唯一列值可能不唯一时可能需要创建复合索引,在复合索引中,应该注意索引列的顺序,总是使选择性最高的列作为索引的第1列。

五 创建和管理索引的一般性指南
oracle的文档《 Oracle Database Administrators Guide》中总结了创建和管理索引的一般性指南,对于其中指导性的一些规则,下面会详细介绍。
1)在导入表数据之后创建索引当使用SQL* Loader或其他的导入工具向表中插入数据时,如果表中已经存在索引,则会导致在每一行插入时 Oracle要维护每一个素引,从而导致导入速度变慢,因此应该考虑在加载数据前先删除索引或禁用索引,在导入数据之后恢复或创建索引。
2)只在需要时创建索引在一个较大的表中, Oracle建议如果频繁访问的数据少于15%或更低,那么应该创建索引,为了提高多表査询的性能,应该在被用于连接的列上创建索引;对于很小的表不用建索引,使用全表扫描反而更快。
3)索引列的排序对性能的影响复合索引列的排序顺序也会影响到性能,总是将使用较频繁的列放到最前面。
4)限制在一个表是的索引的个数
在一个表上可以具有任意多的索引,不过索引越多会导致对表的DML操作越慢,因此应该规划索引的个数,避免创建过多的索引而严重影响到对表操作的性能。
5)索引不再使用时应该即时删除
在索引不再需要时,比如当表变得非常小使得索引影响了性能,或者是表变得很大而索引的条目很小时,可以考虑重建索引。如果指定的索引并没有被任何查询使用,或者是在重新创建索引时必须要删除索引。何时创建索引、何时删除索引是一个非常广命题,要深入理解索引的机制与实际数据库的运行情况,需要积累较多的性能优化经验,很多性能优化的图书会详细地介绍索引的最优使用方式,也有一些专门的图书讨论高效使用 Oracle索引,有兴趣的同事可以自行查阅相关的资料。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容