`
vip_ding
  • 浏览: 12890 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

创建索引原则

阅读更多

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索引

索引编排表

反转键索引

基于函数的索引

分区索引

本地和全局索引


Oracle的索引原理

 

1. 不要进行全表扫描(Full Table Scan):全表扫描导致大量的I/O

  2. 尽量建好和使用好索引:建索引也是有讲究的,在建索引时,也不是索引越多越好,当一个表的索引达到4个以上时,ORACLE的性能可能还是改善不了,因为OLTP系统每表超过5个索引即会降低性能,而且在一个sql 中, Oracle 从不能使用超过 5个索引;当我们用到GROUP BY和ORDER BY时,ORACLE就会自动对数据进行排序,而ORACLE在INIT.ORA中决定了sort_area_size区的大小,当排序不能在我们给定的排序区完成时,ORACLE就会在磁盘中进行排序,也就是我们讲的临时表空间中排序, 过多的磁盘排序将会令 free buffer waits 的值变高,而这个区间并不只是用于排序的,对于开发人员我提出如下忠告:

  1)、select,update,delete 语句中的子查询应当有规律地查找少于20%的表行.如果一个语句查找的行数超过总行数的20%,它将不能通过使用索引获得性能上的提高.

  2)、索引可能产生碎片,因为记录从表中删除时,相应也从表的索引中删除.表释放的空间可以再用,而索引释放的空间却不能再用.频繁进行删除操作的被索引的表,应当阶段性地重建索引,以避免在索引中造成空间碎片,影响性能.在许可的条件下,也可以阶段性地truncate表,truncate命令删除表中所有记录,也删除索引碎片.

  3)、在使用索引时一定要按索引对应字段的顺序进行引用。

  4)、用(+)比用NOT IN更有效率。

  降低ORACLE的竞争:

  先讲几个ORACLE的几个参数,这几个参数关系到ORACLE的竞争:

  1)、freelists 和 freelist 组:他们负责ORACLE的处理表和索引的空间管理;

  2)、pctfree 及 pctused:该参数决定了freelists 和 freelist 组的行为,pctfree 和pctused 参数的唯一目的就是为了控制块如何在 freelists 中进出

  设置好pctfree 及 pctused对块在freelists的移走和读取很重要。

  其他参数的设置

  1)、包括SGA区(系统全局区):系统全局区(SGA)是一个分配给Oracle 的包含一个 Oracle 实例的数据库的控制信息内存段。

  主要包括数据库高速缓存(the database buffer cache),

  重演日志缓存(the redo log buffer),

  共享池(the shared pool),

  数据字典缓存(the data dictionary cache)以及其它各方面的信息

 

如何改善Oracle的索引

1、速度因素
  
  >>PARALLEL选项:当创建索引时,Oracle首先会进行全表扫描来收集符号键和ROWID对,而PARALLEL选项允许多处理器并行扫描表,这样就会加速索引的创建过程。一般推荐的PARALLEL值为CPU数减1。
  
  >>NOLOGGING选项:NOLOGGING选项因为不写日志,所以大大提高了性能,比不使用NOLOGGING选项大约会节省70%的
时间。使用NOLOGGING创建索引的唯一风险就是如果数据库需要做前滚恢复,你将不得不重建索引。
  
  2、空间和结构因素
  
  >>COMPRESS选项:COMPRESS选项用于在创建非唯一性索引时压缩重复值。对于连接索引(即索引包含多列)来说,COMPRESS选项会使索引的大小减少一半以上。COMPRESS选项也可以设置连接索引的前置长度。
  
  >>使用大BLOCKSIZE的表空间:将索引建立在大BLOCKSIZE的表空间上,将大大降低索引树的层次

 

分享到:
评论

相关推荐

    数据库 创建索引 sql oracle

    1.索引的创建与使用 2.创建索引的原则 3.索引的分类 4.创建索引的多种方法 5.管理索引 6.索引优化 7.查看、修改索引属性 8.修改索引名 9.删除索引

    Oracle 创建索引的基本规则

    Oracle 创建索引的基本规则,好好研究一下有好处.

    MySQL组合索引与最左匹配原则详解

    为什么不对没一列创建索引 减少开销 覆盖索引 效率高 减少开销:假如对col1、col2、col3创建组合索引,相当于创建了(col1)、(col1,col2)、(col1,col2,col3)3个索引 覆盖索引:假如查询SELECT col1, col2...

    第08章_索引的创建与设计原则.pdf

    第08章_索引的创建与设计原则.pdf

    SQL 如何建立索引来加快数据库的查询

    创建索引5.1. 自动创建索引5.2. 手动创建索引5.2.1. 创建表时创建索引5.2.2. 在已经存在的表上创建索引5.2.2.1. alter语句创建索引5.2.2.2. create语句创建索引6. 查看索引6.1. explain关键字查看索引6.2. show ...

    浅谈mysql的索引设计原则以及常见索引的区别

    为了使索引的使用效率更高,在创建索引时,必须考虑在哪些字段上创建索引和创建什么类型的索引。 那么索引设计原则又是怎样的? 1.选择唯一性索引 唯一性索引的值是唯一的,可以更快速的通过该索引来确定某条记录。...

    MySQL索引不会被用到的情况汇总

    1.创建索引 代码如下: CREATE INDEX indexName ON mytable(username(length)); 如果是 CHAR,VARCHAR 类型,length 可以小于字段实际长度;如果是 BLOB 和 TEXT 类型,必须指定 length,下同。 2.修改表结构 代码如

    数据库 索引

    1.2 创建索引的优点 (1)创建唯一性索引,保证数据库表中每一行数据的唯一性。 (2)加快数据的检索速度,这也是创建索引的最主要的原因。 (3)减少磁盘IO(向字典一样可以直接定位)。 (4)通过使用索引,可以在...

    简单了解添加mysql索引的3条原则

    一,索引的重要性 索引用于快速找出在某个列中有一特定值的行。不使用索引,MySQL必须从第1条记录开始然后读完整个表直到找出相关的行。表越大,花费的时间越多。如果表中查询的列有一个索引,MySQL能快速到达一个...

    mysql索引优化分享

    关于mysql索引一些优化介绍与创建原则,还有对order by排序的算法的介绍等等

    SQL Server系统调优解决方案

    索引键:用于创建索引的列。 索引类型  聚集索引: 聚集索引基于数据行的键值在表内排序和存储这些数据行。由于数据行按基于聚集索引键的排序次序存储,因此聚集索引对查找行很有效。每个表只能有一个聚集索引,...

    Mysql面试过关!(详解:索引+常用引擎+常见问题+sql调优)

    3.6 查询条件使用or关键字,其中一个字段没有创建索引,则会导致整个查询语句索引失效; or两边为“&gt;”和“&lt;”范围查询时,索引失效 3.7 两列数据做比较,即便两列都创建了索引,索引也会失效 3.8 查询条件使用不等...

    关于MySQL面试题中有关索引的九大难点全在这里了

    数据结构维度 oB+树索引:所有数据存储在...o联合索引:多个字段创建的索引,使用时遵循最左前缀原则。 o唯一索引:索引列中的值必须是唯一的,但是允许为空值。 空间索引:MySQL5.7之后支持空间索引,在空间索引这方面

    MySQL数据库面试题(2020最新版)

    文章目录数据库基础知识为什么要使用数据库什么是SQL?什么是MySQL?数据库三大范式是什么mysql有关权限...创建索引的原则(重中之重)创建索引的三种方式,删除索引创建索引时需要注意什么?使用索引查询一定能提高查询

    C++编程思想,用简单的例子和简练的叙述讲解C++编程,别具特色。

    2.3 放在一起:项目创建工具 29 2.4 什么是非正常 29 2.5 基本对象 30 2.6 什么是对象 34 2.7 抽象数据类型 35 2.8 对象细节 35 2.9 头文件形式 36 2.10 嵌套结构 37 2.11 小结 41 2.12 练习 41 第3章 隐藏实现 42 ...

    MySql数据库索引详解,索引看这一篇就够了

    3 索引的创建和删除 4 索引的执行过程 5 索引的底层实现原理 6 主键索引,辅助索引,聚集索引,非聚集索引 6.1 MyISAM存储引擎-主键索引 6.2 MyISAM存储引擎-辅助索引 6.3 InnoDB存储引擎-主键索引 6.4 InnoDB存储...

    2022年MySQL最新面试题,很全,已拿大厂 offer

    3、创建索引的原则是什么?(重中之重) 4、使用索引查询一定能提高查询的性能吗?为什么 5、索引有哪些优缺点? 6、讲一讲聚簇索引与非聚簇索引? 7、百万级别或以上的数据如何删除 8、什么是最左前缀原则?什么是最...

    深入浅析Mysql联合索引最左匹配原则

    在mysql建立联合索引时会遵循最左前缀匹配的原则,即最左优先,在检索数据时从联合索引的最左边开始匹配,示例: 对列col1、列col2和列col3建一个联合索引 KEY test_col1_col2_col3 on test(col1,col2,col3); 联合...

    mysql索引原理深入解析

    不生产资源,只是资源的搬运工,如有侵权,请及时联系,谢谢! 目录: 一、 索引是什么? 二、 索引存储模型推演 三. B+Tree 落地形式 四、 索引使用原则 五. 索引的创建与使用

    MySQL只学有用的–MYSQL索引原理及创建技巧

    二叉树聊一聊InnoDB的索引模型(B+树)索引的维护(《新华字典》的目录修改)SQL索引执行过程–回表索引创建技巧–索引覆盖索引创建技巧—最左前缀原则索引下推小结引用交个朋友好吗? 索引的基础理解 索引是数据库...

Global site tag (gtag.js) - Google Analytics