新書推薦:
《
中国王朝内争实录:宠位厮杀
》
售價:NT$
281.0
《
凡事发生皆有利于我(这是一本读了之后会让人运气变好的书”治愈无数读者的心理自助经典)
》
售價:NT$
203.0
《
未来特工局
》
售價:NT$
254.0
《
高术莫用(十周年纪念版 逝去的武林续篇 薛颠传世之作 武学尊师李仲轩家世 凸显京津地区一支世家的百年沉浮)
》
售價:NT$
250.0
《
英国简史(刘金源教授作品)
》
售價:NT$
449.0
《
便宜货:廉价商品与美国消费社会的形成
》
售價:NT$
352.0
《
读书是一辈子的事(2024年新版)
》
售價:NT$
352.0
《
乐道文库·什么是秦汉史
》
售價:NT$
367.0
|
編輯推薦: |
唯一专注Oracle数据库索引技术的图书
有的放矢,针对性地提升Oracle性能
Oracle DBA进阶必备
|
內容簡介: |
正确使用Oracle数据库的索引不仅可以实现良好的性能,更重要的是能够创造出可伸缩的数据库应用程序。本书在介绍各种类型索引的过程中,始终围绕性能这一主线,透彻分析了为Oracle数据库创建和优化索引的方方面面。
本书三位作者都是经验丰富的Oracle数据库管理员,拥有创建、使用和维护索引的丰富经验。Darl
Kuhn是Oracle公司高级数据库管理员,Sam R. Alapati是Cash美国国际公司高级数据库架构师,Bill
Padfield则是丹佛一家大型电信公司的首席DBA。三位作者在合作撰写多本广受赞誉的Oracle图书之后再次联手,在这本专门探讨数据库索引的书里,将多年的实践经验和心得体会和盘托出。读者将在作者睿智、谨慎、敏锐的指引下,深入领会Oracle索引技术的精髓。
如果你是菜鸟,本书可助你迅速掌握Oracle索引技术;如果你是资深Oracle数据库管理员,本书可助你摆脱工作中相关问题的困扰。
|
關於作者: |
Darl Kuhn
Oracle公司高级数据库管理员,负责数据库管理从设计、开发到产品支持的各个方面。他还在美国科罗拉多的雷吉斯大学讲授高级数据库课程。另外,Darl还是落基山Oracle用户组的DBA志愿者,拥有美国科罗拉多州立大学研究生学位。
Sam R. Alapati
Oracle ACE,经验丰富的Oracle数据库管理员(Oracle Database11g
OCP)。目前就职于得克萨斯州沃思堡的Cash美国国际公司,担任高级数据库架构师和经理。撰写过多本数据库管理方面的图书,包括《Oracle
Database 11g数据库管理艺术》、《Oracle Database
11g性能优化攻略》,均已由人民邮电出版社翻译出版。
Bill Padfield
Oracle认证专家,具有近30年的IT行业从业经验,14年以上的Oracle数据库管理经验。目前他在科罗拉多州丹佛市的一家大型电信公司担任首席数据库管理员,协助控制和管理由75个数据库系统组成的大型数据仓库环境。同时,Bill也任教于雷吉斯大学,给研究生讲授数据库课程。
|
目錄:
|
第1章 Oracle 索引
1.1 用索引提高性能
1.2 确定使用哪种类型的索引
1.2.1 B树索引
1.2.2 特定的索引类型
1.3 确定需要建立索引的列
1.3.1 主键列和唯一键列的索引
1.3.2 外键列的索引
1.3.3 其他适合创建索引的列
1.4 索引指南
1.5 小结
第2章 B树索引
2.1 Oracle如何使用B树索引
2.1.1 场景一:所有的数据位于索引块
2.1.2 场景二:索引中不包含所有信息
2.1.3?场景三:只有表块被访问
2.2 准备创建B树索引
2.2.1 在创建前估计索引的大小
2.2.2 为索引创建单独的表空间
2.2.3 从表空间继承存储参数
2.2.4 命名标准
2.3 实现B树索引
2.3.1 创建B树索引
2.3.2 报告索引
2.3.3 显示创建索引的代码
2.3.4 删除B树索引
2.4 管理带约束的B树索引
2.4.1 在主键列上创建B树索引
2.4.2 在唯一键列上创建B树索引
2.4.3 索引外键列
2.5 小结
第3章 位图索引
3.1 位图索引
3.2 创建位图索引
3.3 创建分区的位图索引
3.4 在索引组织表上创建位图索引
3.5 位图索引对查询性能的影响
3.6 位图索引对数据载入性能的影响
3.7 了解位图连接索引
3.8 创建位图连接索引
3.9 报告位图索引
3.10 小结
第4章 索引组织表
4.1 索引组织表的结构
4.2 索引组织表的优势
4.3 创建索引组织表
4.4 添加溢出段
4.5 压缩索引组织表
4.6 构建二级索引
4.7 重建索引组织表
4.8 索引组织表报告
4.9 小结
第5章 专门索引
5.1 不可见索引
5.1.1 不可见索引的用途
5.1.2 创建不可见索引
5.1.3 在数据库中查找不可见索引
5.1.4 让优化器使用不可见索引
5.1.5 维护不可见索引
5.2 基于函数的索引
5.2.1 创建基于函数的索引
5.2.2 基于函数的索引的限制
5.2.3 收集基于函数的索引的统计信息
5.3 虚拟列上的索引
5.4 键压缩索引
5.4.1 键压缩的用途
5.4.2 创建压缩索引
5.4.3 键压缩和存储
5.5 复合索引
5.5.1 了解索引跳跃式扫描和复合索引
5.5.2 在复合索引中对列进行排列
5.5.3 为复合索引选择键
5.6 创建虚拟索引
5.7 反向键索引
5.7.1 反向键索引的缺点
5.7.2 反向键索引的用途
5.7.3 创建反向键索引
5.8 应用程序域索引
5.9 小结
第6章 分区索引
6.1 分区索引
6.2 创建本地分区索引
6.2.1 最简单的形式
6.2.2 分区级的需求
6.2.3 前缀和非前缀选项
6.3 管理主键和唯一索引
6.4 创建全局分区索引
6.5 为应用程序选择索引
6.6 维护分区表的索引
6.6.1 添加分区
6.6.2 截断分区
6.6.3 移动分区
6.6.4 拆分分区
6.6.5 交换分区
6.6.6 删除分区
6.6.7 合并分区
6.7 重建全局分区索引和非分区索引
6.8 把索引分区设置为不可用后重建
6.9 索引对间隔分区的影响
6.10 使旧的数据只读
6.11 报告分区索引
6.12 小结
第7章 索引使用调优
7.1 优化器访问路径
7.2 索引扫描
7.2.1 索引唯一扫描
7.2.2 索引范围扫描
7.2.3 索引跳跃式扫描
7.2.4 全索引扫描
7.2.5 索引快速全扫描
7.3 确定查询是否使用了索引
7.4 避免使用索引
7.4.1 在任何情况下都不使用某个索引
7.4.2 只避免快速扫描
7.4.3 强制表扫描
7.5 在索引和表扫描之间选择
7.6 优化器忽略索引的原因
7.6.1 不同的行数
7.6.2 索引聚簇因子
7.7 索引访问路径因没有新的统计信息而改变
7.7.1 使用不等条件
7.7.2 使用通配符查询
7.7.3 在谓词中引用空值
7.7.4 在查询中包含函数
7.7.5 跳过索引的前导部分
7.8 强制优化器使用索引
7.8.1 应用INDEX提示
7.8.2 应用相关的提示
7.8.3 对失败的索引提示进行诊断
7.8.4 调整optimizer_index_cost_adj参数
7.8.5 为索引收集准确的统计信息
7.9 并行化索引访问
7.10 小结
第8章 维护索引
8.1 收集索引统计信息
8.1.1 DBMS_STATS包
8.1.2 METHOD_OPT参数
8.2 处理不可用索引
8.2.1 使索引不可用
8.2.2 指定SKIP_UNUSABLE_INDEXES参数
8.3 管理索引使用的空间
8.3.1 重建索引以减少碎片
8.3.2 重建反向键索引
8.3.3 回收未使用的空间
8.3.4 重建分区索引
8.3.5 频繁重建索引
8.4 INDEX_STATS视图在重建索引时的作用
8.4.1 INDEX_STATS视图的优点
8.4.2 INDEX_STATS视图的问题
8.5 关于重建索引的争论
8.5.1 重建索引的理由
8.5.2 反对重建的理由
8.5.3 关于重建索引的建议
8.6 合并索引来减少碎片
8.7 收缩索引以减少碎片
8.8 移动表和索引
8.9 提高创建索引的效率
8.9.1 并行创建索引
8.9.2 避免在索引创建期间生成重做
8.9.3 使用较大的块
8.9.4 压缩索引
8.9.5 同时使用多个选项
8.10 生成DDL从而创建索引
8.10.1 使用DBMS_METADATA包
8.10.2 使用SESSION_TRANSFORM存储过程
8.10.3 使用SET_FILTER存储过程
8.10.4 使用数据泵
8.11 删除索引
8.12 小结
第9章 SQL调优顾问
9.1 工具之间的联系
9.2 自动SQL调优作业
9.2.1 验证自动作业在运行
9.2.2 查看自动SQL调优作业中的建议
9.2.3 生成SQL脚本来实施自动调优建议
9.2.4 禁用和启用自动SQL调优
9.3 管理SQL调优集
9.3.1 在AWR中查看占用大量资源的SQL
9.3.2 查看内存中使用大量资源的SQL
9.3.3 用AWR中占用大量资源的SQL填充SQL调优集
9.3.4 用内存中占用大量资源的SQL填充SQL调优集
9.3.5 用内存中所有的SQL来填充SQL调优集
9.3.6 显示SQL调优集的内容
9.3.7 选择性删除SQL调优集中的语句
9.3.8 将语句添加到现有的SQL调优集
9.3.9 删除SQL调优集
9.4 运行SQL调优顾问
9.4.1 创建调优任务
9.4.2 执行DBMS_SQLTUNE并查看建议
9.4.3 查看和删除调优任务
9.4.4 从SQL Developer中运行SQL调优顾问
9.4.5 从企业管理器运行SQL调优顾问
9.5 小结
第10章 SQL访问顾问
10.1 为单个SQL语句生成的建议
10.2 获得一组SQL语句的建议
10.3 查询顾问视图
10.4 小结
|
內容試閱:
|
Oracle 索引
索引是一种可以选择创建的数据库对象,它主要用于提高查询性能。数据库索引的用途与一本书后面的索引类似。书的索引把书的主题和页码进行关联。想在一本书中查找信息时,首先检查索引,从中找到要查的主题,确定相关的页码,通常比直接翻书查找要快得多。有了索引提供的信息,就可以直接翻到这本书中的具体页码。如果某个主题只在书的几页内出现,那么读取的页面数量是很少的。采用这种方式,一个主题在书中出现的次数越多,索引对它产生的作用就越小。
与书的索引类似,数据库索引把用户感兴趣的列值连同其行标识符(ROWID)存储在一起。ROWID包含了存储列值的表行在磁盘上的物理位置。有了ROWID,Oracle可以通过最少量的磁盘读取,有效地检索表中的数据。采用这种方式,索引的功能就像表中数据的快捷方式。如果没有可用的索引,那么Oracle就必须读取表中的每一行,才能确定该行是否包含所需的信息。
?注意
除了提高性能,Oracle还使用索引来协助强制执行已启用的主键和唯一键约束。此外,当为外键列建立索引时,Oracle可以更好地管理表锁定的情况。
虽然也可以构建不带索引的数据库应用程序,但该程序性能往往是很差的。即使对于非常大的数据集,索引也具有出色的可伸缩性。那么,既然索引对数据库性能是如此重要,为什么不为所有的表和列组合创建索引呢?答案很简单,索引不是没有代价的,它们消耗磁盘空间和系统资源。在列值被修改的同时也必须更新相应的索引。因此,索引使用了存储空间、IO、CPU和内存资源。创建十分糟糕的索引,会浪费磁盘空间,并且会过度消耗系统资源,也会导致数据库的性能下降。
由于这些原因,在设计和构建基于Oracle数据库的应用程序时,必须从极专业的角度考虑索引策略。作为一名应用程序架构师,你必须了解索引的属性,知道有什么类型的索引可用,并懂得应该选择哪些表和列的组合来创建索引。要想让数据库实现最高性能,正确的索引方法是十分关键的。
本章将介绍Oracle索引的概念。开始我们用一个简明扼要的例子介绍索引是如何提高查询性能的。然后,解释Oracle中可用的索引类型并提供一些指导方针和建议,帮你决定选择为哪些列创建索引。如果你不太清楚如何使用索引,或需要重温相关知识,那么请从这里开始。
1.1 用索引提高性能
索引究竟是如何提高查询性能的呢?要了解索引的工作原理,可以参考如下简单的例子。假设你创建了一个表用来保存客户信息,它的结构类似下面这样:
假设由于业务增长很快,因此在很短的时间内就创建了数以百万计的客户。每日你都对此表执行报表查询,并注意到发出下面这样的查询语句时,性能在逐步降低。
当表中数据很少时,该查询一瞬间就返回结果。现在,表中有超过一百万行的数据,而且数据还在继续增长,这个查询花费的时间就越来越长。这是怎么回事?
当执行一个SELECT语句时,Oracle查询优化器快速计算出每一步的执行计划,这个计划详细地说明了将如何检索查询中指定的列值。在计算该计划时,优化器确定检索数据将用到哪些表和索引。
当不存在索引时,表本身是能满足查询结果的唯一访问路径。在这种情况下,Oracle别无选择,只能检查表的每一数据块内的每一行(这被称为全表扫描),看看是否有姓(last_name)是STARK的行。随着表中插入越来越多的数据,查询需要的时间越来越长。此查询的成本(以CPU、内存和IO资源消耗来衡量)与表的数据块的数量成正比。要想使这个查询运行速度更快,只能购买更好的硬件或使用一种增强性能的功能,如索引。
你可以“向前”翻阅一下本章内容,这样可以确定SQL查询的WHERE子句中出现的列的索引可能会提高性能,于是我们为CUST表的LAST_NAME列创建索引,像这样:
这条语句创建一个B树索引(稍后详细解释)。这是Oracle默认的索引类型。创建索引后,按last_name选择的查询用时就能恢复到一秒内。不错吧?
要了解索引是如何提高性能的,首先要记得索引存储了两种类型的信息:表中的列值和相应的ROWID。在数据库内,ROWID可唯一标识一行(对于堆组织表),并包含其物理位置(数据文件和数据块内行的位置)。创建了索引并执行后续查询后,查询优化器判断该索引是否能减少返回查询结果所需的资源量。
提示
ROWID唯一标识堆组织表的一行。然而,对于聚簇表,有可能出现这种情况:不同表中的行位于同一数据块内,并具有相同的ROWID。
在前一个例子中,假设CUST表中的记录有数百万,但表中只有一个记录的LAST_NAME是STARK。那么查询优化器可以检查索引,并仅通过几个磁盘读,就能找到表中某个块的确切位置(通过ROWID),其中包含符合查询条件的记录,这使得查询速度非常快。在这种情况下,即使表中有数百万行记录也不要紧,只要该索引所包含的值是相当独特的,Oracle都能够通过极少量的磁盘读取操作返回所需的行。
相反,考虑一下LAST_NAME列的值不是很独特的情况。假设CUST表中有几百万的记录都包含了LEE值。如果查询优化器使用索引,就必须从索引中读取数百万次,检索出所有的ROWID,然后再(通过ROWID)从表读数百万次。在这种情况下,不使用索引而直接扫描表中每个块的速度更快。出于这个原因,有时优化器计算出使用索引并不能提高性能,就会忽略它。
提示
B树索引中值的独特性程度越高,它就越有效。在数据库术语中,与表的总行数相比,有很多可选择的(很独特的)列值,这种情况被称为具有高基数。相反,低基数是指与表的总行数相比,独特值很少的情况。
我们还应该指出另外一个有趣的情况。假设不是查询CUST表的所有列值,而是只查询LAST_NAME列,会怎么样呢?
在这种情况下,因为该索引包含SELECT子句中的所有列值,Oracle只需访问索引就能够满足查询的结果,而不必读取表结构本身。当SELECT子句中的列都具有索引时,这种索引称为覆盖索引。这些索引特别有效,因为只需要读取索引块。
在继续学习之前,先回顾一下本章到目前为止所介绍的内容。
索引是一种可选对象,它是在一个表的一个或多个列上定义的。
索引要消耗资源。
B树索引是Oracle默认的索引类型。
在表中值最独特的列上创建B树索引效率最高。
创建合适的索引能提高性能。
在某些情况下,查询优化器会选择不使用索引。换言之,查询优化器这时计算出全表扫描的成本低于使用索引时的成本。
在某些情况下,Oracle只需访问索引就可以检索出要查询的数据,而无需对表进行访问。
了解这些有关索引的基础知识,为理解本章和本书其余部分将介绍的概念提供了良好的基础。现在,让我们把注意力转到确定使用哪种类型的索引上。
1.2 确定使用哪种类型的索引
Oracle提供了丰富的索引类型和功能。正确地使用索引可以产生良好的性能和可伸缩的数据库应用程序。相反,如果不正确或不明智地实现某一个功能,有可能对性能造成损害。表1-1总结了Oracle的各种索引类型。乍一看,这是个长长的清单,在Oracle的初学者看来可能有点难以招架。实际上,作出使用哪个索引类型的决定可能不像最初看上去那么困难。对于大多数应用程序,只需要使用默认的B树索引类型即可。
注意
有几个在表1-1中列出的索引类型,其实只是基本的B树索引的变种。例如,反向键索引,仅仅是一种当索引值是顺序生成并插入类似值时,为了均匀地分散IO而进行了优化的B树索引。
表1-1 Oracle索引的类型和功能说明
索引类型 用途
B树
默认的索引类型,平衡树索引,适用于高基数(不同值的程度高)的列。除非有特殊原因需要使用不同的索引类型或功能,否则用正常的B树索引即可
索引组织表 当主键包含大多数的列值时很有效率。访问这种索引就像访问表一样。数据存储在一个类似B树的结构中
唯一索引 B树索引的一种形式,用于强制执行列值的唯一性。经常与主键和唯一键约束一起使用,但也可以独立于约束而创建
反向键索引 B树索引的一种形式,在索引有许多顺序插入的情况下,用于平衡IO
键压缩索引 适用于前导列经常重复的组合索引,压缩叶块条目。此功能适用于B树索引或IOT(索引组织表)索引
降序索引
B树索引的一种形式,在索引对应的列值按降序(默认的顺序是升序)排序时使用。反向键索引不能指定降序,如果是位图索引,那么Oracle忽略降序
位图索引
对于包含低基数列以及在SQL语句的WHERE子句中使用许多AND或OR运算符的数据仓库环境,非常适合使用这种索引。位图索引不适合经常更新行的在线事务处理(OLTP)数据库。无法创建唯一的位图索引
位图连接索引 在数据仓库环境中,对于利用连接事实表和维表的星型模式结构的查询非常有用
基于函数的索引 适用于应用了SQL函数的列。可与B树索引类型或位图索引类型结合使用
虚拟列索引 在表的虚拟列上定义的索引,适用于应用了SQL函数的列,可用来替代基于函数的索引
虚拟索引 允许通过CREATE
INDEX的NOSEGMENT子句创建没有物理段或区的索引,在调优SQL时有用,因无需建立物理索引从而避免消耗资源。任何类型的索引都可以创建为虚拟的
不可见索引
该索引对查询优化器是不可见的。然而,在表中的数据被修改的同时也维护索引结构。用于在使索引对应用程序可见之前测试它。任何类型的索引都可以创建为不可见的
全局分区索引 跨分区表的所有分区或常规表的全局索引。它的类型可以是B树索引,而不能是位图索引
本地分区索引 本地索引基于分区表的单个分区。它的类型可以是B树索引或位图索引
域索引 用于具体的应用程序或程序模块
B树聚簇索引 用于聚簇表
散列聚簇索引 用于散列聚簇
以下几节简要介绍B树索引和另外几种索引。必要时,我们会指出本书接下来哪一章中将全面讨论某种索引。
1.2.1 B树索引
首先说明一下,B树索引将在第2章完整介绍。本节介绍它们是为了与其他类型的索引进行比较。如前所述,Oracle默认的索引类型是B树索引。对于高基数的列值,该索引类型是非常有效的。对于大多数应用程序,该索引类型是合适的。
不指定任何选项的情况下,CREATE INDEX语句创建B树索引,需要提供索引的名称、表名和列名。
除非有已核实的性能方面的原因需要使用其他的索引类型,否则应当使用B树索引。DBA或开发人员读到一种新的索引功能,就以为供应商的夸张宣传的功能符合应用程序的实际实现的利益,这种情况比比皆是。在你选择实现一种新的索引类型或功能时,请确认是否有充足的理由。
B树索引有多个子类型:
索引组织表;
唯一索引;
反向键索引;
键压缩索引;
降序索引。
接下来的几个小节将简要介绍这些B树索引的子类型。
1. 索引组织表
索引组织表(IOT)在一个B树索引结构中存储表行的全部内容。使用索引组织表,能缩短具有精确匹配和主键范围搜索的查询时间。
尽管索引组织表是作为B树索引结构实现的,但它还是通过CREATE TABLE...ORGANIZATION
INDEX语句创建的。例如,
注意 关于索引组织表的实现细节,请参阅第4章。
2. 唯一索引
当创建B树索引时,可以定义它是唯一索引。在这方面,它就像唯一键约束。当插入数据到相应的表时,唯一索引将保证插入到表中的非空值都是不同的。出于这个原因,唯一索引通常与主键和唯一键约束联合使用(完整的详细信息,请参阅第2章)。
通过CREATE UNIQUE INDEX语句指定创建唯一索引。
注意
请参阅第2章,全面了解创建唯一索引与允许Oracle在定义主键或唯一键约束时,自动创建索引这两种方法的优点和缺点。
3. 反向键索引
反向键索引对于平衡有大量顺序插入的索引的IO是非常有用的。在需要一种方式均匀地分布索引数据,以避免将相似的值聚集在一起时,这些索引表现更好。因此,当插入大量顺序值时,如果使用反向键索引,就可以避免IO集中在索引内的某个物理磁盘位置。这种索引类型将在第5章进一步讨论。
反向键索引通过REVERSE子句指定,如下所示:
注意 不能对位图索引或索引组织表指定REVERSE子句。另外,反向键索引不能是降序类型的。
4. 键压缩索引
键压缩索引有助于减少前导列经常重复的组合索引的存储和IO要求。使用compress N子句创建压缩的索引。
注意 不能在位图索引上创建键压缩索引。
5. 降序索引
默认情况下,Oracle用升序方式存储B树索引。例如,如果在一个列值为数值型数据的列上创建索引,最小的数值将首先出现在索引(最左边的叶节点)中,而最大的数值将被储存在最右边的叶节点上。
通过对一列指定DESC关键字可以指示Oracle反转这种顺序为降序。这将创建降序索引。例如,
降序索引对于某些列以升序排序而另一些列以降序排序的查询是有用的。
1.2.2 特定的索引类型
有时B树索引对于提供所需的性能改善是不够的。以下是在特定的情况下应使用的索引类型:
位图索引;
位图连接索引;
基于函数的索引;
虚拟列索引;
不可见索引;
全局分区索引;
本地分区索引;
域索引;
B树聚簇索引;
散列聚簇索引。
以下小节分别简要介绍了以上类型的索引。这些索引类型中的大部分,将在接下来几章详细介绍。
1. 位图索引
位图索引通常用在数据仓库环境中。这些索引适用于具有相对较低数量不同值(低基数)的列。
对于在WHERE子句中使用多个AND或OR连接操作的SQL语句(在数据仓库环境中,这是典型的查询),位图索引也是高效的。
在经常执行INSERTUPDATEDELETE等操作的OLTP数据库中不应该使用位图索引。这是因为位图索引的结构导致在许多单独的DML操作期间锁定多个行(从而导致高事务的OLTP系统中的锁定问题)。
使用关键字BITMAP创建位图索引。为了保持例子的完整性,我们也显示准备建立位图索引的表的创建脚本。
注意 位图索引和位图连接索引只在Oracle企业版数据库中提供。
2. 位图连接索引
位图连接索引在索引中存储两个表之间的连接结果。这些索引是有益的,因为它们避免了检索结果时对表进行连接。在使用一个表的外键列和另一个表的主键列连接两个表时,适合用位图连接索引。
位图连接索引通常适合于有定期批量加载,然后不作更新的表的数据仓库环境。当更新有位图连接索引的表时,这可能导致多行被锁定。因此,这种类型的索引不适合OLTP数据库。位图连接索引用关键字BITMAP指定,并且必须提供一个连接条件。如下面的例子所示(为了保持例子的完整性,我们也显示需要连接表的创建语句):
注意 位图索引和位图连接索引是第3章的重点。
3. 基于函数的索引
基于函数的索引用其定义中的SQL函数或表达式创建。基于函数的索引允许在被查询的WHERE子句中SQL函数引用的列使用索引查找。下面的例子创建基于函数的索引:
这些类型的索引是必要的,因为查询引用一个应用了SQL函数的列时,Oracle将无法使用正常的B树索引。
注意 基于函数的索引可以为B树索引、唯一索引或位图索引。
4. 虚拟列索引
一种代替基于函数的索引的方法是在表中添加一个虚拟列,然后为虚拟列创建索引。你必须通过测试来确定在基于函数的索引和虚拟列的索引究竟哪种更适合你的性能要求。
下面列举一个简要的例子。假设有一个INV表,在它上面创建了一个虚拟列。
现在就可以在虚拟列上创建常规索引。
注意 虚拟列功能只在Oracle Database 11g和更高版本中才提供。
5. 虚拟索引
通过NOSEGMENT子句可以指示Oracle创建永远不会被使用的索引,并且不会将任何区分配给它的索引。
尽管该索引没有实例化,但还是可以通过_USE_NOSEGMENT_INDEXES初始化参数指示Oracle来确定该索引是否可能被优化器使用。例如:
在什么情况下这个功能有用?如果你想创建一个非常大的索引,并且不分配空间,以便确定优化器是否会用到它,那就可以使用NOSEGMENT创建索引并进行测试。如果确定该索引有用,再删除该索引并使用不带NOSEGMENT子句的命令重新创建它。
6. 不可见索引
不可见索引意味着优化器为查询语句检索数据时不使用该索引。然而,当对基础表插入、更新或删除记录时,数据库仍然在维护该索引结构。如果想在不影响现有应用程序代码的前提下,测试索引的可行性,就可以使用此功能。使用INVISIBLE关键字来创建不可见索引。
注意 不可见索引只有在Oracle Database 11g和更高版本中才提供。
7. 全局和本地分区索引
分区索引在逻辑上是一个索引,但实际上它是在几个不同的段中实现的。这能保证即使是非常大的数据库也能具有良好的性能。分区索引可以是全局的也可以是本地的。
注意 分区选项需要额外付费购买,只在Oracle数据库企业版中提供。
全局分区索引是使用分区策略的索引,但这种分区并不映射到基础表的段。可以为常规表或分区表建立全局分区索引。全局分区索引实现为B树类型,并且可以定义为唯一索引。使用GLOBAL
PARTITION子句创建全局分区索引。如下例子创建了由范围界定的全局分区索引:
本地分区索引必须建立在分区表上。这种索引与其基础表遵循相同的分区策略。本地分区索引的分区只包含其相应的表分区中的值。本地分区索引可以是B树索引或位图索引。使用LOCAL
关键字创建此类型的索引。为了保持例子的完整性,下面也给出了作为本地分区索引基础的分区表的创建语句。
注意 分区索引是第6章的重点。
域索引、B树聚簇索引和散列聚簇索引
应用程序域索引是针对一个特定的应用程序自定义的。一般适合在自定义数据类型、文档、图像、视频和空间数据。
B树聚簇索引是聚簇表键上定义的索引。B树聚簇索引将一个聚簇键与一个数据库块地址相关联。该索引类型与聚簇表一同使用。类似地,散列聚簇索引也用于聚簇表,散列聚簇索引与B树聚簇索引的差异是,前者使用散列函数取代了索引键。
注意
本书没有过多介绍域索引、B树聚簇索引和散列聚簇索引。如果需要了解更多有关这些索引类型的信息,请参阅Oracle的SQL参考指南,网址是http:otn.oracle.com。
1.3 确定需要建立索引的列
现在我们把注意力转到应为哪些列建立索引上。对于初学者来说,我们建议对于大多数应用程序,在下列情况下创建索引。
为每个表定义主键约束:这导致在主键指定的列上自动创建索引。
在要求唯一且不同于主键列的列上创建唯一键约束:每个唯一键约束导致在约束中指定的列上自动创建一个索引。
手动创建外键列上的索引:这是为了得到更好的性能,以避免某些特定的锁问题(有关完整的详细信息,请参阅第2章)。
以下小节中将详细介绍以上列出的每个项目。
提示 请参阅第9章,了解从SQL调优顾问(SQL Tuning
Advisor)获得索引建议的相关内容。参阅第10章,了解从SQL访问顾问(SQL Access
Advisor)生成索引建议的相关内容。
1.3.1 主键列和唯一键列的索引
在大多数情况下,应该为每个表创建主键约束。如果没有为主键列定义索引,那么Oracle会自动为你创建一个B树索引。
同样,对于在表上定义的任何唯一键约束,如果唯一键列上没有已定义的索引,Oracle也将创建一个合适的B树索引,如下面简单的例子所示:
请参阅第2章,了解关于主键和唯一键约束的完整细节以及它们与索引的关系。
1.3.2 外键列的索引
Oracle不会自动创建外键列的索引。我们建议在外键列上创建B树索引的原因之一是,外键列经常在WHERE子句中被引用,并因此可以改善这些查询的性能。
当外键列上存在索引时,可以避免或减少锁定问题。也就是说,当插入或删除子表中的记录时,将在父表上放置一个表级别的锁,该锁将阻止其他进程在父表中插入或删除记录。在OLTP数据库中,当有多个进程同时插入和删除父表和子表中的记录时,这可能会成问题。在数据仓库环境中,这个问题的影响更小,因为数据以更加系统化的方式(调度批处理作业)被加载并且数据通常不会被删除。
下面是一个简单的例子,首先创建一个有外键的表,然后手动创建索引:
1.3.3 其他适合创建索引的列
在选择创建什么样的索引时,请牢记这一基本原则:根据查询表时使用的列制定索引策略。既可以在一个表上创建多个索引,也可以创建一个包含多个列的索引。如果事先考虑好需要在表上执行什么类型的查询,那么就会做出更好的决策。如果你已经确定了性能较差的SQL查询,也可以考虑为符合以下条件的列创建索引。
为经常用作WHERE子句中谓词的列创建索引,如果在WHERE子句中使用表的多个列,可以考虑使用组合(多列)索引。
为在SELECT子句中使用的列创建覆盖索引。
考虑为在ORDER BY、GROUP BY、UNION或者DISTINCT子句中使用的列创建索引。
Oracle允许创建包含多个列的索引。多列索引被称为组合索引(有时也被称为复合索引)。如果你访问表时经常在WHERE子句中使用多个列,那么这些索引特别有效。在这种情况下,组合索引常常比分别创建多个单列索引更有效。
包含在SELECT和WHERE子句中的列也是索引的候选者。请记得,覆盖索引包括查询返回的所有列。在这种情况下,Oracle可以使用索引结构本身(而不是表)来满足查询的结果。此外,如果列值有足够的选择性,Oracle还可以使用WHERE子句中引用的列的索引来提高查询性能。
还应考虑为在GROUP BY、ORDER
BY、UNION或DISTINCT子句中使用的列建立索引。这可能会使经常使用这些SQL构造的查询更高效。
每个表上有多个索引没有关系。但是,在一个表上建立的索引越多,DML语句就会运行得越慢(因为表列值变化时,Oracle有越来越多的索引需要维护)。不要在表中随机添加索引,直到偶然发现索引列的正确组合,这是一个陷阱。相反,需要在生产环境中创建索引之前,验证它的性能。(关于验证性能优势的详细信息,请参阅第7章)。
注意 表中的一列允许在该表的多个索引中出现。然而,Oracle并不允许在一个表的完全相同的列组合上创建多个索引。
1.4 索引指南
利用Oracle索引有助于高效访问大型数据集。只有确定了SELECT语句在性能上的改进与索引所消耗的空间成本和更新表时的开销相比是否值得,才能确定是否应该使用索引。表1-2概括了有效使用索引的准则。
表1-2 创建索引的准则
指南 论证
创建所需数量的索引,但尽量少创建索引。明智地添加索引。首先要测试以确定可量化的性能收益
索引提高性能,但也消耗磁盘空间和处理资源。不要添加不必要的索引
(续)
指南 论证
对表执行的查询所需的性能,应该成为制订索引策略的基础 为在SQL查询中使用的列创建索引将最大限度地提升性能
考虑使用SQL调优顾问或SQL访问顾问获得索引的建议 这些工具提供了建议和第二双进行索引决策的眼睛
为所有表创建主键约束 这将自动创建一个B树索引(如果在主键列上还没有建立索引)
在合适的地方创建唯一键约束 这将自动创建一个B树索引(如果在唯一键列上还没有建立索引)
为包含外键的列创建索引 连接表时,外键列通常包含在WHERE子句中,从而能提高SQL
SELECT语句的性能。在外键列上创建一个B树索引,还可以减少在更新和插入子表时的锁定问题
小心地选择和测试小表的索引(小表少于几千行) 即使对于小表,有时候访问索引也可能比全表扫描性能更好
使用正确的索引类型 正确使用索引能最大限度地提高性能。参见表1-1了解更多详细内容
如果不能证明使用不同类型索引可获得性能增益,那就使用基本的B树索引类型
对于大多数具有高基数列值的应用程序,都适合使用B树索引
数据仓库环境中,考虑使用位图索引
对不经常更新的低基数值列来说,使用这些索引是理想选择。位图索引适用于星型模式事实表的外键列,前提是经常会对事实表运行使用AND和OR连接条件的查询
考虑为索引使用单独的表空间(与表分离)
表和索引数据可能有不同的存储、备份和恢复要求。单独的表空间,可以把索引和表分开管理
让索引从表空间继承它的存储属性 这使得它更易于管理和维护索引的存储
使用一致的命名标准 这使得维护和故障排除更容易
不要重建索引,除非有充分的理由这样做 重建索引通常是不必要的,除非索引损坏或需要把索引移动到不同的表空间
监测索引,并删除不被使用的索引 这样做能释放物理空间,并提高DML(数据操纵语言)语句的性能
删除索引之前,考虑把它标记为不可用或不可见的
这使你在删除索引之前,可以更好地确定是否有任何性能问题。这些选项使得可以重建或重新启用索引而无需用DDL(数据定义语言)来创建语句
在创建和管理数据库中的索引时,请参考这些指导原则。这些建议是为了帮助你正确使用索引技术。
1.5 小结
索引的存在主要是为了提高查询性能,因此仔细考虑如何实现索引是至关重要的。精心设计的索引策略将会使数据库应用程序的性能优异。相反,欠考虑的计划将导致性能不佳。
索引占用磁盘空间,并与表分开存放。然而,索引定义在表的一个或多个列上,从这个意义上说,索引不能脱离表而单独存在。
Oracle提供了广泛的索引类型和功能。在大多数情况下,使用默认的B树索引就可以了。使用其他类型的索引之前,请确保你了解性能收益。你应该知道Oracle提供的索引有哪些功能,并知道在什么样的情况下,应该使用哪种专门的索引。
我们建议在主键列、唯一键列和外键列上创建索引。这是个很好的起点。然后,对执行缓慢的SQL语句进行分析,观察会用到哪些列。这会为你提供额外的候选索引列。这些索引建议奠定了最大限度地提高SQL查询性能的基础。
……
|
|