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列有一个索引,查询语句仍然执行一次全表扫描。 
   
  select cust_Id,cust_name 
  from  customers 
  where cust_rating <> ‘aa‘; 
   
  把上面的语句改成如下的查询语句,这样,在采用基于规则的优化器而不是基于代价的优化器(更智能)时,将会使用索引。 
   
  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子句中对存在索引的列使用函数时,会使优化器忽略掉这些索引。 
   
  下面的查询不会使用索引(只要它不是基于函数的索引) 
   
  select empno,ename,deptno 
  from  emp 
  where trunc(hiredate)=‘01-MAY-81‘; 
   
  把上面的语句改成下面的语句,这样就可以通过索引进行查找。 
   
  select empno,ename,deptno 
  from  emp 
  where hiredate<(to_date(‘01-MAY-81‘)+0.9999); 
   
  4.4 比较不匹配的数据类型 
   
  比较不匹配的数据类型也是比较难于发现的性能问题之一。 
   
  注意下面查询的例子,account_number是一个VARCHAR2类型,在account_number字段上有索引。下面的语句将执行全表扫描。 
   
  select bank_name,address,city,state,zip 
  from  banks 
  where account_number = 990354; 
  Oracle可以自动把where子句变成to_number(account_number)=990354,这样就限制了索引的使用,改成下面的查询就可以使用索引: 
  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子句中。索引跳跃式扫描比全索引扫描要快的多。下面的程序清单显示出性能的差别: 
   
  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 0  SORT(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 0  SORT(AGGREGATE) 
  2 1   INDEX(SKIP SCAN) OF ‘SKIP1‘(NON-UNIQUE) 
   
  Statistics 
   
  21 consistent gets 
  17 physical  reads 
   
  [10] 索引的类型 
  B-树索引 
  位图索引 
  HASH索引 
  索引编排表 
  反转键索引 
  基于函数的索引 
  分区索引 
  本地和全局索引

=================

避免全表扫描

时间: 2024-11-08 22:14:45

Oracle优化经典文章------索引原理篇的相关文章

SQL优化 &#183; 经典案例 &#183; 索引篇

Introduction 在这些年的工作之中,由于SQL问题导致的数据库故障层出不穷,下面将过去六年工作中遇到的SQL问题总结归类,还原问题原貌,给出分析问题思路和解决问题的方法,帮助用户在使用数据库的过程中能够少走一些弯路.总共包括四部分:索引篇,SQL改写篇,参数优化篇,优化器篇四部分,今天将介绍第一部分:索引篇. 索引问题是SQL问题中出现频率最高的,常见的索引问题包括:无索引,隐式转换.当数据库中出现访问表的SQL无索引导致全表扫描,如果表的数据量很大,扫描大量的数据,应用请求变慢占用数

Lucene底层原理和优化经验分享(1)-Lucene简介和索引原理

基于Lucene检索引擎我们开发了自己的全文检索系统,承担起后台PB级.万亿条数据记录的检索工作,这里向大家分享下Lucene底层原理研究和一些优化经验. 从两个方面介绍: 1. Lucene简介和索引原理 2. Lucene优化经验总结 1. Lucene简介和索引原理 该部分从三方面展开:Lucene简介.索引原理.Lucene索引实现. 1.1 Lucene简介 Lucene最初由鼎鼎大名Doug Cutting开发,2000年开源,现在也是开源全文检索方案的不二选择,它的特点概述起来就是

SQL Server索引 (原理、存储)聚集索引、非聚集索引、堆 &lt;第一篇&gt;

一.存储结构 在SQL Server中,有许多不同的可用排列规则选项. 二进制:按字符的数字表示形式排序(ASCII码中,用数字32表示空格,用68表示字母"D").因为所有内容都表示为数字,所以处理起来速度最快,遗憾的是,它并不总是如人们所想象,在WHERE子句中进行比较时,使用该选项会造成严重的混乱. 字典顺序:这种排序方式与在字典中看到的排序方式一样,但是少有不同,可以设置大量不同的额外选项来决定是否区分大小写.音调和字符集. 1.平衡树(B-树) 平衡树或B-树仅是提供了一种以

SQL索引一步到位(此文章为“数据库性能优化二:数据库表优化”附属文章之一)

SQL索引一步到位(此文章为“数据库性能优化二:数据库表优化”附属文章之一) SQL索引在数据库优化中占有一个非常大的比例, 一个好的索引的设计,可以让你的效率提高几十甚至几百倍,在这里将带你一步步揭开他的神秘面纱. 1.1 什么是索引? SQL索引有两种,聚集索引和非聚集索引,索引主要目的是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间 下面举两个简单的例子: 图书馆的例子:一个图书馆那么多书,怎么管理呢?建立一个字母开头的目录,例如:a开头的书,在第一排,b开头

MySQL优化之索引原理(二)

一,前言 ? 上一篇内容说到了MySQL存储引擎的相关内容,及数据类型的选择优化.下面再来说说索引的内容,包括对B-Tree和B+Tree两者的区别. 1.1,什么是索引 ? 索引是存储引擎用于快速找到记录的一种数据结构, 对性能的提升有很大的帮助,尤其当表中数量较大的情况下,索引正确的使用可以对性能提升几个数量级. 但是索引经常被忽略,不恰当的索引对性能可能还会带来负面效果. 1.2,什么时候添加索引 主键自动建立主键索引(唯一索引) where字句中的列,频繁作为查询字段的列 表连接关联的列

Oracle SQL 经典查询练手第三篇

Oracle SQL 经典查询练手第三篇 本文分享的是Oracle SQL的经典查询第三篇,仅仅是作者自己的见解,如有问题,希望您给出建议或者方法.同时,欢迎广大读者们补充,如果您有经典的查询方式也可以拿出来我们共同分享,共同成长,共同进步. 本计算机上使用的是Oracle 11.2.0版本,使用scott用户登陆.使用的是系统自带的表. 表结构: describe employees; describe departments; describe locations; select *from

MySQL数据库学习【第九篇】索引原理与慢查询优化

一.介绍 1.什么是索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句的优化显然是重中之重.说起加速查询,就不得不提到索引了. 2.为什么要有索引呢? 索引在MySQL中也叫做"键",是存储引擎用于快速找到记录的一种数据结构.索引对于良好的性能非常关键,尤其是当表中的数据量越来越大时,索引对于性能的影响愈发重要.索引优化应该是对查询性能优化最有效的手段了.

重新学习MySQL数据库5:根据MySQL索引原理进行分析与优化

重新学习MySQL数据库5:根据MySQL索引原理进行分析与优化 一:Mysql原理与慢查询 MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓"好马配好鞍",如何能够更好的使用它,已经成为开发工程师的必修课,我们经常会从职位描述上看到诸如"精通MySQL"."SQL语句优化"."了解数据库原理"等要求.我们知道一般的应用系统,读写比例在10:1左右,而且插入

MySQL索引原理及优化

一.各种数据结构介绍 这一小节结合哈希表.完全平衡二叉树.B树以及B+树的优缺点来介绍为什么选择B+树. 假如有这么一张表(表名:sanguo): (1)Hash索引 对name字段建立哈希索引: 根据name字段值进行hash计算,定位到数组的下标,因为字段值所对应的数组下标是哈希算法随机算出来的,所以可能出现哈希冲突.其中每一个节点存储的是name字段值及对应的行数据地址,那么对于这样一个索引结构,现在来执行下面的sql语句:  select * from sanguo where name