一、索引概述

     索引(index),它是数据库必不可少的一部分。它其实很简单呐!很好理解。
     索引好比如一本书的目录,一张地图,一个写字楼里挂在大堂墙上的公司名录,一个地铁站的出口指示牌。
     关系型数据库技术的精髓就是通过关系表进行规范化的数据存储,并通过各种表连接技术和各种类型的索引技术来进行信息的检索和处理。合理的索引策略将保证各种操作的高效和快捷,没有合理的索引,将不得不按表进行全部遍历,这意味着退回到文件系统的处理方式,更意味着资源、时间的大量消耗。

 
 

二、索引类型简介

     Oracle数据提供了许许多多中不同的索引来满足数据库设计者的需要,当且仅当SQL查询语句包含where子句的时候,才会触发它的使用。数据库先对where子句进行评估,然后决定是否需要使用索引,哪种索引提供的数据访问更快。以下简单罗列了那些笑得花枝烂灿,我不认识他,他也不认识我的索引们。
索引名称 注释
B Tree index(B*索引) 最经典、常用的索引
Primary Key 主键,也是索引
Unique Key 唯一索引
Function-Based Index 函数索引
Composite Index 多字段复合索引
Reverse Index 反转索引
Bitmap Index 位图索引
Bitmap-join Index 位图连接索引
Cluster Index 簇索引
Cluster-Hash Index 簇哈希索引
Local Perfix Partitioned Index 本地前缀分区索引
Local non-Prefix Partitioned Index 本地非前缀分区索引
Global Range-Partitioned Index 全局哈希分区索引
Global Hash-Partitioned Index 全局范围分区索引
Context Index 全文搜索索引
CTXCAT Index 文献目录索引
CTXRULE Index 文献分类索引
CTXXPATH Index XML类型的全文索引
 
     大家看到啦!其实做一枚Oracle索引专家其实很简单啦!挨个背下来,当然上面我所列举的还不是全部索引哟!然后挨个背下来全部索引的含义,特别是优缺点和适应场景。背下来了么?恭喜你,你已经是专家了!当上CEO,迎娶白富美,走上人生巅峰!就此一举!
     好吧,事实告诉我们,大多数男人都是不举的,不然导阳索也不会那么畅销!
     好吧,新一代中文命名的索引算法问世了——导阳索。

 
 

三、Oracle索引原理简介

     An index is an optional structure,associated with a table or table cluster,that can sometimes speed data access.By create an index on one or more columns of a table,you gain the ability in some cases to retrieve a small set of randomly distributed rows from the table.Indexs are one of many means of reducing disk I/O.
     索引作为一种可选数据结构,联合了单表与多表的数据,从而使得某些数据访问高效。通过在表里创建一个或者更多的索引,您获得了查询任意行分散于表中的任意行。索引的使用常常意味着减少磁盘读写压力。
     各种索引长的都不太一样。下面只介绍最常用的B Tree Index(B*索引)。
     
     (1)、门牌号码:RowId
     在数据库中,每条记录都有自己的物理地址,叫做RowId。包括所属的数据文件号、数据块号,以及在该数据块中的具体位置等信息。
     (2)、索引就是目录
     索引就是一个本书的目录。索引包括被索引的字段值和所对应的RowId,分别相当于目录中的书条目和对应的页码。

 
 

四、单子段索引设计建议

     以下只是针对B Tree Index单子段索引的设计建议,(引自《品悟性能优化》罗敏)
  • 分析SQL语句中的约束条件字段;
  • 如果约束条件字段不固定,建议创建针对单字段的普通B Tree Index;
  • 选择可选性最高的字段建立索引;
  • 如果是多表连接SQL语句,注意被驱动表(drived table)的连接字段是否需要创建索引;
  • 通过多种SQL分析工具,分析执行计划并以量化形式评估效果;
 

 
 

五、函数索引设计建议

     函数索引使得SQL不需要进行复杂的语句转换,提高语句的可读性。但是函数索引尽量少用,而将函数进行转换,原因如下:
  • 函数索引需要维护。当数据库每次进行该表的输入、删除、修改操作时,Oracle都需要维护函数索引,也就是说需要进行一次计算,维护成本将高于普通索引。
  • 函数索引的计算值可能大于原字段值,将消耗更多的索引存储空间。

 
 

六、复合索引原理和设计建议

     (1)、复合索引的第一个原理:前缀性(Prefixing)
     先从例子说起。架设省、市、县分别用3个字段存储数据,并建立一个复合索引。该复合索引在数据库索引树上是如下排列的,即先按省排序,再按市排序,最后按县排序:

提示:Oracle索引,包括复合索引都是排序的。

县|区
北京 北京 东城
北京 北京 西城
北京 北京 海淀
…… …… ……
黑龙江 哈尔滨 道里区
黑龙江 哈尔滨 道外区
黑龙江 哈尔滨 香坊区
…… …… ……
黑龙江 齐齐哈尔 龙沙区
黑龙江 齐齐哈尔 铁峰区
黑龙江 齐齐哈尔 富拉尔基区
…… …… ……
四川省 成都市 青羊区
四川省 成都市 金牛区
四川省 成都市 武侯区
…… …… ……
四川省 泸州市 江阳区
四川省 泸州市 龙马潭区
四川省 泸州市 古蔺县
…… …… ……
      Oracle并没采用人工智能算法,只会按图索骥,依着索引结构是先按省排序的,所以只要给出省名,就能使用索引。如果没有省名,Oracle就成了无头苍蝇,蜕化回全表扫描(full table scan)。
      举个栗子,如果只给予县|区条件,如“道里区”,Oracle肯定不会使用索引。
 
     (2)、关于skip scan index
      对于Oracle比较熟悉的同学,一定知道在Oracle 9i提供的skip scan index功能。INDEX_SS Hint(强制使用index skip scan 的方式访问索引
     Index skip scan功能适合于什么情况呢?如果Oracle发现第一个字段值很少的情况下。
 

例如:

     EMP表有GENDER(性别)字段,并且建立了(GENDER、EName、Job)复合索引。因为性别只有男和女,所以为了提高索引利用率,Oracle可将这个索引拆成("man"、EName、Job)和("women"、EName、Job)两个复合索引。这样即便没有GENDER条件,Oracle也会分别到男索引树和女索引树进行搜索。
     但是,这种复合索引本身设计是不合理的,因为它违背了复合索引的第二个原理:可选性(Selectivity)。
 
    (3)、复合索引的第二个原理:可选性(Selectivity)
     Oracle建议按字段可选性高低进行排列复合索引中的字段顺序,即字段值多的排在前面。
 

例如:

     (Job、EName、GENDER),(县、市、省)。这是因为,字段值多,可选性越强,定位的记录越少,查询效率越高。

例如:

全国可能只有一个"武侯区",而成都省的记录则太多了。

    (4)、复合索引的设计建议
     综上所述,现在列出一些复合索引的设计建议。
  1. 分析SQL语句中的约束条件字段,(约束字段相对较少进行delete、update操作,这样索引碎片也会相应变少);
  2. 如果约束条件字段比较固定,则优先考虑创建针对多字段的普通B Tree复合索引。例如同时涉及到月份、参与人代号、参与机构代码3个字段的条件,则可以考虑建立一个复合索引;
  3. 如果单个字段是主键或唯一字段,或者可选性非常高的字段,尽管约束条件字段比较固定,也不一定要建成复合索引,可建成单子段索引,降低复合索引开销;
  4. 在复合索引设计中,需首先考虑复合索引的第一个设计原理:复合索引的前缀性(perfixing)。即在SQL语句中,只有将复合索引的第一个字段作为约束条件,该复合索引才会启用;
  5. 在复合索引设计中,其次应考虑复合索引的可选性(Selectivity)。即按可选性高低,进行复合索引字段的排序。
  6. 如果条件涉及的字段不固定,组合比较灵活,则分别为月份、参与人代号、参与机构代码3个字段建立索引。
  7. 如果是多表连接SQL语句,注意是否可以在被驱动表(drived table)的连接字段与该表的其他约束条件字段上创建复合索引。
  8. 通过多种SQL分析工具,分析执行计划并以量化形式评估效果。

 
 

 为什么索引I/O那么高

     在很多系统里面,常常会发现索引表空间I/O非常高,甚至超过了数据表空间。在主要等待事件中,“db file sequential read”也比较高。这种情况说明在整个数据库系统中,索引的读写操作比较多,已经成为系统的主要瓶颈。
     这种情况一般是由如下原因导致的。
  1. 应用软件质量较高,大量SQL语句均采用了索引;
  2. 可能有一些索引没有被利用上,同时DML操作较为频繁,导致索引的维护工作量增加,即产生了大量不必要的索引I/O;
  3. 由于频繁的DML操作,可能导致了大量的索引碎片,增加了索引I/O开销;
  4. 部分索引设计不合理,虽然使用了索引,但实际上是全索引扫描(index full scan),实际上类似于全表扫描(full table scan);
     上述第一种原因是正常的,第四种情况实际上在前面关于索引建立策略方面已经讲述了。下面将对第二、第三种原因进行分析。
     如何发现多余的索引?
    (1)、根据原理判断
     根据复合索引的前缀性和可选性两大原理,去分析这张表各字段的记录分布情况,根据具体字段情况作出合并、整合的判断。
 
    (2)、利用Oracle索引监控特性
     利用Oracle 所提供的索引监控特性,在某个典型业务周期开始之前,分别执行如下命令对需要关注的索引启用监控和结束监控:
SQL> alter index <索引名> monitoring usage;
SQL> alter index <索引名> nomonitoring usage;
     查询如下视图,则能知道在这个典型业务周期之内,这个索引到底有没有用了。

SQL> select * from v$object_usage;

     拿着证据,把乱建索引的同学抓入法网,让他看着我们亲自删除索引。


八、索引碎片分析和整理
     频繁对索引字段进行delete、update操作,会对索引造成大量碎片,从而极大地影响索引的使用效率,并造成索引I/O的增加。
     (1)、索引碎片分析
     执行如下语句可监测索引的碎片情况:
analyze index <索引名> validate structure online;
select name,del_lf_rows_len,lf_rows_len,(del_lf_rows_len/lf_rows_len)*100 from index_stats; 
     表中:索引碎片率(%)=(del_lf_rows_len/lf_rows_len)*100。
     如果索引碎片率超过20%,则Oracle认为索引碎片已经非常严重。
 
     (2)、索引碎片整理
     Oracle进行索引碎片的处理包裹两种策略。
  • 重建索引(Rebuild)

SQL> alter index <索引名> rebuild;

  • 压缩索引(Coalesce)

SQL> alter index <索引名> coalesce;

 
 
系列博客:

品味性能之道<一>:性能测试思维与误区

品味性能之道<二>:性能工程师可以具备的专业素养

品味性能之道<三>:方法论

品味性能之道<四>:管理重于技术

品味性能之道<五>:SQL分析工具

品味性能之道<六>:图形化SQL分析工具

品味性能之道<七>:索引基础

品味性能之道<八>:Loadrunner关联技巧与字符处理

品味性能之道<九>:利用Loadrunner编写socket性能测试脚本简述

品味性能之道<十>:Oracle Hint

品味性能之道<十一>:JAVA中switch和if性能比较

深入理解Loadrunner中的Browser Emulation

使用Loadrunner对IBM MQ进行性能测试

怎么做性能测试--响应时间

品味性能之道<七>:索引基础的更多相关文章

  1. 品味性能之道<九>:利用Loadrunner编写socket性能测试脚本简述

            一.概述         Loadrunner拥有极为丰富的工具箱,供予我们制造出各种奇妙魔法的能力.其中就有此次要讨论的socket套接字操作.     二.socket概述     ...

  2. 品味性能之道<十一>:JAVA中switch和if性能比较

    通常而言大家普遍的认知里switch case的效率高于if else.根据我的理解而言switch的查找类似于二叉树,if则是线性查找.按照此逻辑推理对于对比条件数目大于3时switch更优,并且对 ...

  3. 品味性能之道<十>:Oracle Hint

    Hint 是Oracle 提供的一种SQL语法,它允许用户在SQL语句中插入相关的语法,从而影响SQL的执行方式. 因为Hint的特殊作用,所以对于开发人员不应该在代码中使用它,Hint 更像是Ora ...

  4. 品味性能之道<八>:Loadrunner关联技巧与字符处理

    一.概述       Loadrunner作为HP出品的性能测试工具,拥有太多奇妙魔法甜点供予性能测试人员享用,其中吃起来比较有嚼劲的那就是关联了.当然在关联之后我们还需要一些简单的字符处理,用以生成 ...

  5. 品味性能之道<六>:图形化SQL分析工具

         在上一章里,重点分享了命令行SQL分析工具的使用方法.在本章将重点分享PL/SQL的SQL分析工具. 一.如何打开PL/SQL执行计划      开启PL/SQL这工具,推荐如下方法: 点击 ...

  6. 品味性能之道<五>:SQL分析工具

    一.SQL语句到底是怎么执行的? 想了解SQL语句到底是怎么执行的,那就需要进行SQL语句执行计划分析. 那什么是SQL语句执行计划呢? 就是Oracle服务器执行SQL语句的过程.例如确定是否使用索 ...

  7. 品味性能之道<三>:方法论

    自顶向下的性能优化方法论 系统优化是包括系统设计.开发.产品上线.平台优化的全过程,不同阶段的优化工作对全系统所带来的效益是不同的.理想的性能优化论应该采用自顶向下的优化方法,即在项目设计.开发和上线 ...

  8. 品味性能之道<四>:管理重于技术

      一.性能优化中的角色分工 (1).老外的角色分工         在oracle性能优化方法论中,将IT系统中不同角色需要承担的性能优化工作罗列如下. 各司其职的角色分工 业务分析人员 1.业务需 ...

  9. 品味性能之道<二>:性能工程师可以具备的专业素养

          性能工程师可以具备的专业素养 程序语言原理,包括:C.C++.java及jvm.ASP,因为建站大部分外围应用和中间件都是JAVA编写,大部分的电商平台采用的ASP编写,底层核心系统是C/ ...

随机推荐

  1. ajax 使用 三种方法 设置csrf_token的装饰器

    1. CSRF中间件   CSRF跨站请求伪造 2. 补充两个装饰器  from django.views.decorators.csrf import csrf_exempt, csrf_prote ...

  2. spring boot 静态变量注入配置文件

    spring 静态变量注入 spring 中不支持直接进行静态变量值的注入,我们看一下代码: @Component(value = "KafkaConfig") @Configur ...

  3. node进阶之用流实现上传文件

    内容: 1.文件上传基础 2.node文件处理机制 3.用流实现文件上传 1.文件上传基础 前端代码: <form action="localhost:8080/" meth ...

  4. python中键值叫唤例子

    >>> myDict = {'a':'A','b':'B','c':'C'} >>> myDict {'a': 'A', 'c': 'C', 'b': 'B'} & ...

  5. 2018-2019-2 《网络对抗技术》Exp1 PC平台逆向破解 Week3 20165233

    Exp1 PC平台逆向破解 实验内容 一.基础知识点 NOP, JNE, JE, JMP, CMP汇编指令的机器码 NOP指令即"空指令",执行到NOP指令时,CPU什么也不做,机 ...

  6. UnicodeDecodeError: 'gbk' codec can't decode byte 0xae in position 120: illegal multibyte sequence

    UnicodeDecodeError: 'gbk' codec can't decode byte 0xae in position 120: illegal multibyte sequence f ...

  7. psc格式的文件是什么

    psc格式的文件是什么 是navicat 这个工具导出的数据文件 可以使用备份还原功能  提取sql

  8. leetcode944

    public class Solution { public int MinDeletionSize(string[] A) { ; ; j < A[].Length; j++) { ; i & ...

  9. leetcode485

    public class Solution { public int FindMaxConsecutiveOnes(int[] nums) { ; ; ; i < nums.Length; i+ ...

  10. 14 MySQL--事务&函数与流程控制

    一.事务 事务用于将某些操作的多个SQL作为原子性操作,一旦有某一个出现错误,即可回滚到原来的状态,从而保证数据库数据完整性. 一堆sql语句:要么同时执行成功,要么同时失败 # 事务的原子性 场景: ...