1.什么是索引
    索引是建立在表的一列或多个列上的辅助对象,目的是加快访问表中的数据;
  Oracle存储索引的数据结构是B*树,位图索引也是如此,只不过是叶子节点不同B*数索引;
  索引由根节点、分支节点和叶子节点组成,上级索引块包含下级索引块的索引数据,叶节点包含索引数据和确定行实际位置的rowid。
  使用索引的目的
  加快查询速度
  减少I/O操作
  消除磁盘排序
  何时使用索引
  查询返回的记录数
  排序表<40%
  非排序表 <7%
  表的碎片较多(频繁增加、删除)

  2.索引的种类
  非唯一索引(最常用)
  唯一索引
  位图索引
  局部有前缀分区索引
  局部无前缀分区索引
  全局有前缀分区索引
  散列分区索引
  基于函数的索引
  3.管理索引的准则
  
  在表中插入数据后创建索引
  在用SQL*Loader或import工具插入或装载数据后,建立索引比较有效;
    3.1索引正确的表和列
   经常检索排序大表中40%或非排序表7%的行,建议建索引;
  。为了改善多表关联,索引列用于联结;
  。列中的值相对比较唯一;
  。取值范围(大:B*树索引,小:位图索引);
  。Date型列一般适合基于函数的索引;
  。列中有许多空值,不适合建立索引
  
  3.2为性能而安排索引列
  
  。经常一起使用多个字段检索记录,组合索引比单索引更有效;
  。把最常用的列放在最前面,例:dx_groupid_serv_id(groupid,serv_id),在where条件中使用groupid或groupid,serv_id,查询将使用索引,若仅用到serv_id字段,则索引无效;
  3.3合并/拆分不必要的索引。
  
  3.4限制每个表索引的数量
  
  。一个表可以有几百个索引(你会这样做吗?),但是对于频繁插入和更新表,索引越多系统CPU,I/O负担就越重;
  。建议每张表不超过5个索引。
  
  3.5删除不再需要的索引
  
  。索引无效,集中表现在该使用基于函数的索引或位图索引,而使用了B*树索引;
  。应用中的查询不使用索引;
  。重建索引之前必须先删除索引,若用alter index … rebuild重建索引,则不必删除索引。
  
  3.6索引数据块空间使用
  。创建索引时指定表空间,特别是在建立主键时,应明确指定表空间;
  。合理设定pctfress,注意:不能给索引指定pctused;
  。估计索引的大小和合理地设置存储参数,默认为表空间大小,或initial与next设置成一样大。
  3.7考虑并行创建索引
  。对大表可以采用并行创建索引,在并行创建索引时,存储参数被每个查询服务器进程分别使用,例如:initial为1M,并行度为8,则创建索引期间至少要消耗8M空间;
  3.8考虑用nologging创建索引
  。对大表创建索引可以使用nologging来减少重做日志;
  。节省重做日志文件的空间;
  。缩短创建索引的时间;
  。改善了并行创建大索引时的性能。

4.怎样建立最佳索引
  
  明确地创建索引
  create index index_name on table_name(field_name)
  tablespace tablespace_name
  pctfree 5
  initrans 2
  maxtrans 255
  storage
  (
  minextents 1
  maxextents 16382
  pctincrease 0
  );
  
  创建基于函数的索引
  
  。常用与UPPER、LOWER、TO_CHAR(date)等函数分类上,例:
  create index idx_func on emp (UPPER(ename)) tablespace tablespace_name;
  
  创建位图索引
  
  。对基数较小,且基数相对稳定的列建立索引时,首先应该考虑位图索引,例:
  create bitmap index idx_bitm on class (classno) tablespace tablespace_name;
  
  明确地创建唯一索引
  
  。可以用create unique index语句来创建唯一索引,例:
  create unique index dept_unique_idx on dept(dept_no) tablespace idx_1;
  
  创建与约束相关的索引
  
  。可以用using index字句,为与unique和primary key约束相关的索引,例如:
  alter table table_name
  add constraint PK_primary_keyname primary key (field_name)
  using index tablespace tablespace_name;
  
  5.如何创建局部分区索引
  
  。基础表必须是分区表;
  。分区数量与基础表相同;
  。每个索引分区的子分区数量与相应的基础表分区相同;
  。基础表的子分区中的行的索引项,被存储在该索引的相应的子分区中,例如:
  Create Index TG_CDR04_SERV_ID_IDX On TG_CDR04(SERV_ID)
  Pctfree 5
  Tablespace TBS_AK01_IDX
  Storage (
  MaxExtents 32768
  PctIncrease 0
  FreeLists 1
  FreeList Groups 1
  )
  local
  /
  
  6如何创建范围分区的全局索引
  
  。基础表可以是全局表和分区表。
  create index idx_start_date on tg_cdr01(start_date)
  global partition by range(start_date)
  (partition p01_idx vlaues less than (‘0106’)
  partition p01_idx vlaues less than (‘0111’)
  …
  partition p01_idx vlaues less than (‘0401’ ))
  /
  重建现存的索引
  重建现存的索引的当前时刻不会影响查询;
  
  重建索引可以删除额外的数据块;
  提高索引查询效率;
  alter index idx_name rebuild nologging;
  
  对于分区索引:
  alter index idx_name rebuild partition partiton_name nologging;
  
  7.要删除索引的原因
  
  。不再需要的索引;
  。索引没有针对其相关的表所发布的查询提供所期望的性能改善;
  。应用没有用该索引来查询数据;
  。该索引无效,必须在重建之前删除该索引;
  。该索引已经变的太碎了,必须在重建之前删除该索引;
  。语句:drop index idx_name;drop index idx_name drop partition partition_name;
  
  8.建立索引的代价
  
  基础表维护时,系统要同时维护索引,不合理的索引将严重影响系统资源,主要表现在CPU和I/O上;
  
  插入、更新、删除数据产生大量db file sequential read锁等待;

一个表中有几百万条数据,对某个字段加了索引,但是查询时性能并没有什么提高,这主要可能是oracle的索引限制造成的。

oracle的索引有一些索引限制,在这些索引限制发生的情况下,即使已经加了索引,oracle还是会执行一次全表扫描,查询的性能不会比不加索引有所提高,反而可能由于数据库维护索引的系统开销造成性能更差。

下面是一些常见的索引限制问题。

9、使用不等于操作符(<>, !=)

下面这种情况,即使在列dept_id有一个索引,查询语句仍然执行一次全表扫描

select * from dept where staff_num <> 1000;

但是开发中的确需要这样的查询,难道没有解决问题的办法了吗?

有!

通过把用 or 语法替代不等号进行查询,就可以使用索引,以避免全表扫描:上面的语句改成下面这样的,就可以使用索引了。

select * from dept shere staff_num < 1000 or dept_id > 1000;

10、使用 is null 或 is not null

使用 is null 或is nuo null也会限制索引的使用,因为数据库并没有定义null值。如果被索引的列中有很多null,就不会使用这个索引(除非索引是一个位图索引,关于位图索引,会在以后的blog文章里做详细解释)。在sql语句中使用null会造成很多麻烦。

解决这个问题的办法就是:建表时把需要索引的列定义为非空(not null)

 11、使用函数

如果没有使用基于函数的索引,那么where子句中对存在索引的列使用函数时,会使优化器忽略掉这些索引。下面的查询就不会使用索引:

select * from staff where trunc(birthdate) = '01-MAY-82';

但是把函数应用在条件上,索引是可以生效的,把上面的语句改成下面的语句,就可以通过索引进行查找。

select * from staff where birthdate < (to_date('01-MAY-82') + 0.9999);

12、比较不匹配的数据类型

比较不匹配的数据类型也是难于发现的性能问题之一。下面的例子中,dept_id是一个varchar2型的字段,在这个字段上有索引,但是下面的语句会执行全表扫描。

select * from dept where dept_id = 900198;

这是因为oracle会自动把where子句转换成to_number(dept_id)=900198,就是3所说的情况,这样就限制了索引的使用。把SQL语句改为如下形式就可以使用索引

select * from dept where dept_id = '900198';

13、使用like子句

使用like子句查询时,数据需要把所有的记录都遍历来进行判断,索引不能发挥作用,这种情况也要尽量避免。

Like 的字符串中第一个字符如果是‘%’则用不到索引
Column1 like ‘aaa%’ 是可以的
Column1 like ‘%aaa%’用不到

14.使用in

尽管In写法要比exists简单一些,exists一般来说性能要比In要高的多
用In还是用Exists的时机
当in的集合比较小的时候,或者用Exists无法用到选择性高的索引的时候,用In要好,否则就要用Exists
例:select count(*) from person_info where xb in (select xb_id from dic_sex);
Select count(*) from n_acntbasic a where shbxdjm =:a and exists(select 1 from person_info where pid=a.pid and …);

Select * from person_info where zjhm=3101….;将会对person_info全表扫描
Select * from person_info where zjhm =‘3101…’才能用到索引

假定TEST表的dt字段是date类型的并且对dt建了索引。
如果要查‘20041010’一天的数据.下面的方法用不到索引
Select * from test where to_char(dt,’yyyymmdd’) =‘20041010’;
而select * from test where dt >=to_date(‘20041010’,’yyyymmdd’) and dt < to_date(‘20041010’,’yyyymmdd’) + 1 将会用到索引。

15.如果能不用到排序,则尽量避免排序。
用到排序的情况有
集合操作。Union ,minus ,intersect等,注:union all 是不排序的。
Order by
Group by
Distinct
In 有时候也会用到排序
确实要排序的时候也尽量要排序小数据量
,尽量让排序在内存中执行,有文章说,内存排序的速度是硬盘排序的1万倍。

ORACLE索引介绍和使用的更多相关文章

  1. 转: ORACLE索引介绍和使用

    1.什么是索引 索引是建立在表的一列或多个列上的辅助对象,目的是加快访问表中的数据: Oracle存储索引的数据结构是B*树,位图索引也是如此,只不过是叶子节点不同B*数索引: 索引由根节点.分支节点 ...

  2. Oracle索引梳理系列(九)- 浅谈聚簇因子对索引使用的影响及优化方法

    版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...

  3. Oracle索引梳理系列(六)- Oracle索引种类之函数索引

    版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...

  4. Oracle索引梳理系列(二)- Oracle索引种类及B树索引

    版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...

  5. Oracle 索引<七>

    Oracle 索引 管理索引-原理介绍  介绍 索引是用于加速数据存取的数据对象.合理的使用索引可以大大降低 i/o 次数,从而提高数据访问性能.索引有很多种我们主要介绍常用的几种: 为什么添加了索 ...

  6. ORACLE索引监控的简单使用

    --ORACLE索引监控的简单使用-------------------------2013/11/20 说明:     应用程序在开发时,可能会建立众多索引,但是这些索引的使用到底怎么样,是否有些索 ...

  7. Oracle索引之Btree索引

    索引介绍 日常开发中,对于数据的查询如果需要优化,常听说要加个索引.但是为什么加了索引,数据的查询就快了呢?那是不是加了索引就一定会是有效或者有利的呢? Oracle中常见有BTREE索引,位图索引和 ...

  8. 转://创建oracle索引时需要注意的7个事项

    在创建Oracle索引时,有一些问题使我们需要注意的,下面就为您介绍创建oracle索引的一些注意事项,希望对您学习创建Oracle索引方面能有所帮助. 1.一般来说,不需要为比较小的表创建索引: 2 ...

  9. 【Oracle】Oracle索引

    在关系数据库中,索引是一种与表有关的数据库结构,它可以使对应于表的SQL语句执行得更快.索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容. 对于数据库来说,索引是一个必选项,但对于现 ...

随机推荐

  1. http trigger 事件源是事件的生产者,函数是事件的处理者

    以函数计算作为 API 网关后端服务_用户指南(开放 API)_API 网关-阿里云  https://help.aliyun.com/document_detail/54788.html 创建触发器 ...

  2. 一起talk C栗子吧(第九十回:C语言实例--使用管道进行进程间通信三)

    各位看官们,大家好,上一回中咱们说的是使用管道进行进程间通信的样例.这一回咱们说的样例是:使用管道进行进程间通信.只是使用管道的方式不同样.闲话休提,言归正转.让我们一起talk C栗子吧! 我们在前 ...

  3. ios26--kvc

    // // main.m // 13-KVC的使用 // /** KVC: Key Value Coding(键值编码):1.取值赋值.2.字典转模型. */ #import <Foundati ...

  4. Codeforces Round #363 (Div. 2)E. LRU

    E. LRU time limit per test 2 seconds memory limit per test 256 megabytes input standard input output ...

  5. Aaron Swartz Rewriting Reddit中关于web.py的创建思路

    这天才少年居然自杀了,哎 原文点这 So how should things work? The first principle is that code should be clear and si ...

  6. openstack horizon 学习(1) 总览

    关于Horizon的设计理念: 来自官网(http://docs.openstack.org/developer/horizon/intro.html): Horizon holds several ...

  7. 洛谷P3216 [HNOI2011]数学作业

    题目描述 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 N 和 M,要求计算 Concatenate (1 .. N) Mod M 的值,其中 Concatenat ...

  8. bzoj1791

    1791: [Ioi2008]Island 岛屿 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1680  Solved: 369[Submit][S ...

  9. jquery plupload上传插件

    http://www.jianshu.com/p/047349275cd4 http://www.cnblogs.com/2050/p/3913184.html demo地址: http://chap ...

  10. P2252 取石子游戏

    传送门 威佐夫博弈结论:若石子数为\(a,b(a<b)\),当且仅当\((y-x)*\frac{(\sqrt{5}+1)}{2}=x\)的时候先手必败 证明 //minamoto #includ ...