`
445822357
  • 浏览: 739388 次
文章分类
社区版块
存档分类
最新评论

Oracle数据库经典优化之索引原理篇

 
阅读更多

Oracle提供了大量索引选项。知道在给定条件下使用哪个选项对于一个应用程序的性能来说非常重要。一个错误的选择可能会引发死锁,并导致数据库性能急剧下降或进程终止。而如果做出正确的选择,则可以合理使用资源,使那些已经运行了几个小时甚至几天的进程在几分钟得以完成,这样会使您立刻成为一位英雄。这篇文章就将简单的讨论每个索引选项。主要有以下内容:

1、基本的索引概念:

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

2、组合索引:

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

特别注意:在Oracle9i之前,只有在使用到索引的前导索引时才可以使用组合索引!

3、Oracle ROWID:

通过每个行的ROWID,索引Oracle提供了访问单行数据的能力。ROWID其实就是直接指向单独行的线路图。如果想检查重复值或是其他对ROWID本身的引用,可以在任何表中使用和指定rowid列。

4、限制索引:

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

4.1 使用不等于操作符(<>、!=):

下面的查询即使在cust_rating列有一个索引,查询语句仍然执行一次全表扫描。

<ccid_nobr></ccid_nobr>
<ccid_code></ccid_code>select cust_Id,cust_name
from  customers
where cust_rating <> 'aa';

把上面的语句改成如下的查询语句,这样,在采用基于规则的优化器而不是基于代价的优化器(更智能)时,将会使用索引。

<ccid_nobr></ccid_nobr>
<ccid_code></ccid_code>select cust_Id,cust_name
from  customers
where cust_rating < 'aa' or cust_rating > 'aa';

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

4.2 使用IS NULL 或IS NOT NULL:

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

4.3 使用函数:

如果不使用基于函数的索引,那么在SQL语句的WHERE子句中对存在索引的列使用函数时,会使优化器忽略掉这些索引。

下面的查询不会使用索引(只要它不是基于函数的索引):

<ccid_nobr></ccid_nobr>
<ccid_code></ccid_code>select empno,ename,deptno
from  emp
where trunc(hiredate)='01-MAY-81';

把上面的语句改成下面的语句,这样就可以通过索引进行查找。

<ccid_nobr></ccid_nobr>
<ccid_code></ccid_code>select empno,ename,deptno
from  emp
where hiredate<(to_date('01-MAY-81')+0.9999);

4.4 比较不匹配的数据类型:

比较不匹配的数据类型也是比较难于发现的性能问题之一。

注意下面查询的例子,account_number是一个VARCHAR2类型,在account_number字段上有索引。下面的语句将执行全表扫描。

<ccid_nobr></ccid_nobr>
<ccid_code></ccid_code>select bank_name,address,city,state,zip
from  banks
where account_number = 990354;

Oracle可以自动把where子句变成to_number(account_number)=990354,这样就限制了索引的使用,改成下面的查询就可以使用索引:

<ccid_nobr></ccid_nobr>
<ccid_code></ccid_code>select bank_name,address,city,state,zip
from  banks
where account_number ='990354';

特别注意:不匹配的数据类型之间比较会让Oracle自动限制索引的使用,即便对这个查询执行Explain Plan也不能让您明白为什么做了一次“全表扫描”。

5、选择性:

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

6、群集因子(Clustering Factor):

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

7、二元高度(Binary height):

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

8、快速全局扫描:

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

9、跳跃式扫描:

从Oracle9i开始,索引跳跃式扫描特性可以允许优化器使用组合索引,即便索引的前导列没有出现在WHERE子句中。索引跳跃式扫描比全索引扫描要快的多。下面的程序清单显示出性能的差别:

<ccid_nobr></ccid_nobr>
<ccid_code></ccid_code>create index skip1 on emp5(job,empno);
index created.

select count(*)
from emp5
where empno=7900;

Elapsed:00:00:03.13

Execution Plan
0 SELECT STATEMENT Optimizer
=CHOOSE(Cost=4 Card=1 Bytes=5)
1 0SORT(AGGREGATE)
2 1 INDEX(FAST FULL SCAN) 
OF 'SKIP1'(NON-UNIQUE)

Statistics

6826 consistent gets
6819 physical  reads

select /*+ index(emp5 skip1)*/ count(*)
from emp5
where empno=7900;

Elapsed:00:00:00.56

Execution Plan
0 SELECT STATEMENT Optimizer
=CHOOSE(Cost=6 Card=1 Bytes=5)
1 0SORT(AGGREGATE)
2 1 INDEX(SKIP SCAN) OF 
'SKIP1'(NON-UNIQUE)

Statistics

21 consistent gets
17 physical  reads

10、索引的类型:

B-树索引 位图索引 HASH索引 索引编排表

反转键索引 基于函数的索引 分区索引 本地和全局索引

分享到:
评论

相关推荐

    Oracle索引优化相关

    Oracle数据库经典优化之索引原理篇 Oracle中建立索引并强制优化器 基于索引的SQL语句优化之降龙十八掌 30个Oracle语句优化规则详解-性能调优

    Oracle DBA手记3-数据库性能优化与内部原理解析 中文版

    《oracle dba手记3:数据库性能优化与内部原理解析》由多位数据库技术专家合著而成,融合了各行业dba 的工作经验与思考,包含了精心挑选的数据库性能优化与内部原理解析案例。内容涵盖“dba 手记”,以手记形式记录...

    高并发Oracle数据库系统的架构与设计

    , 全书主要内容从三个维度展开:首先是内部扩展的维度,深入探讨了高效B树索引、高效表设计、查询优化器等数据库架构设计与优化的核心技术,以及高并发Oracle数据库系统架构与设计的方法论和常见的高并发案例;...

    oracle数据库DBA专题技术精粹.zip

    本书从DBA的角度阐述了Oracle数据库的结构内幕、管理经验和优化技巧,并列举了很多实用的案例。本书主要分为五大部分,基础篇主要介绍了一些基础技术与OCP认证相关的一些内容,内各种平台上安装与建库的技巧以及在9i...

    ORACLE索引详解及SQL优化

    ORACLE索引详解及SQL优化,详细描述了几种常用索引原理以及创建方法,解读索引生效条件,以及在开发中常用的提高数据库效率、降低数据库资源消耗的方法。

    ORACLE数据库中SQL优化解析

    本文介绍了SQL的执行过程,ORACLE优化器的基本原理,优化器的选择和应用,以及如何建立 和管理索引来提高程序的执行效率。并以实际工作经验介绍了优化工具以及提出对SQL优化的体会。

    高并发Oracle数据库系统的架构与设计.pdf

    高并发Oracle数据库系统的架构与设计主要内容从三个维度展开:首先是内部扩展的维度,深入探讨了高效B树索引、高效表设计、查询优化器等数据库架构设计与优化的核心技术,以及高并发Oracle数据库系统架构与设计的...

    基于ORACLE数据库的全文检索技术的安装和使用方法

    互联网上有很多关于数据库全文索引和文件方式全方索引的比较,其主旨都是要充分利用基于关键的索引及其优化算法,原理上也是相通的,相对而言基于文件的全文索引对中文的支持是比较弱的,同时也是一个比较难于...

    oracle数据库11G初学者指南.Oracle.Database.11g,.A.Beginner's.Guide

    7.1 Oracle备份和恢复基本原理 7.1.1 从何处着手 7.1.2 备份的体系结构 7.1.3 Oracle二进制文件 7.1.4 参数文件 7.1.5 控制文件 7.1.6 重做日志 7.1.7 撤消段 7.1.8 检查点 7.1.9 归档日志 7.1.10 数据文件、表空间...

    OracleB_树索引内部机制及其应用的研究

    Oracle数据库应用系统的性能优化是一项系统化的工程,涉及到数据库结构的各个方面。本文从B* 树索引入手, 分析了B* 树索引的结构及原理,阐明了如何正确合理地使用B* 树索引及其如何优化数据库系统的性能。

    Oracle_索引

    介绍数据库索引知识、索引分类及优缺点、索引原理、索引优化

    数据库常见面试题

    1、数据库有哪几种范式? 2、Mysql提供了哪几种事务隔离级别? 3、MySQL中varchar与...16、数据库优化的思路? 17、视图的作用,视图可以更改么? 18、存储过程与触发器的区别? 19、如何在最快时间之内重启500台db?

    oracle SQL性能优化

    ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾. (3) SELECT子句中避免使用 ‘ * ‘: ORACLE在解析的...

Global site tag (gtag.js) - Google Analytics