zoukankan      html  css  js  c++  java
  • 品味性能之道<七>:索引基础

    一、索引概述

         索引(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进行性能测试
    怎么做性能测试--响应时间

  • 相关阅读:
    Vue自定义过滤器格式化数字三位加一逗号
    js复制功能
    vue中数据接收成功,页面渲染失败
    css技巧
    vue+elementUI table篇
    图片预加载
    jquery实现文字自动向上滚动,鼠标放上去停止,移开继续滚动代码...
    【Flutter】广播机制
    【Flutter】IOS打包
    【Flutter】BottomNavigationBar切换页面被重置问题(保存状态)
  • 原文地址:https://www.cnblogs.com/snifferhu/p/3479258.html
Copyright © 2011-2022 走看看