zoukankan      html  css  js  c++  java
  • 数据库索引- 复合索引(多列索引)

    对复合索引,按照字段在查询条件中出现的频度建立索引。在复合索引中,记录首先按照第一个字段排序。对于在第一个字段上取值相同的记录,系统再按照第二个字段的取值排序,以此类推。因此只有复合索引的第一个字段出现在查询条件中,该索引才可能被使用,因此将应用频度高的字段,放置在复合索引的前面,会使系统最大可能地使用此索引,发挥索引的作用。

    二、多列索引适合的场景

           1.全字段匹配

           2.匹配部分最左前缀

           3.匹配第一列

           4.匹配第一列范围查询(可用用like a%,但不能使用like %b)

           5.精确匹配某一列和和范围匹配另外一列

           order by操作中出现的字段同样适用于按值查找的规则,where+order by中出现的字段需可以建立满足如上五种规则多列索引。使用多列所需需要按照最左索引列查找;不能跳过中间列;如果某一列是范围查询,那么其右边所有列无法使用索引。IN什么情况下是范围查询,什么情况下是多个等值查询?如果有order by排序时,多个等于条件查询就是范围查询,没有order by排序就没有限制。

           例如,建立多列索引(name, age, id),只能使用索引的前两列。in是范围查询
    ... where name='nginx.cn' and age in(15,16,17) order by id

           可以使用整个索引,in是按值查询
    ... where name='nginx.cn' and age in(15,16,17) and id ='3'

    三、复合索引的建立以及最左前缀原则

          索引字符串值的前缀(prefixe)。如果你需要索引一个字符串数据列,那么最好在任何适当的情况下都应该指定前缀长度。
    例如,如果有CHAR(200)数据列,如果前面10个或20个字符都不同,就不要索引整个数据列。索引前面10个或20个字符会节省大量的空间。你可以索引CHAR、VARCHAR、BINARY、VARBINARY、BLOB和TEXT数据列的前缀。
            假设你在表的state、city和zip数据列上建立了复合索引。索引中的数据行按照state/city/zip次序排列,因此它们也会自动地按照state/city和state次序排列。这意味着,即使你在查询中只指定了state值,或者指定state和city值,MySQL也可以使用这个索引。因此,这个索引可以被用于搜索如下所示的数据列组合:
           state, city, zip
           state, city
           state
           mysql不能利用这个索引来搜索没有包含在最左前缀的内容。例如,如果你按照city或zip来搜索,就不会使用到这个索引。如果你搜索给定的state和具体的ZIP代码(索引的1和3列),该索引也是不能用于这种组合值的,尽管MySQL可以利用索引来查找匹配的state从而缩小搜索的范围。
            如果你考虑给已经索引过的表添加索引,那么就要考虑你将增加的索引是否是已有的多列索引的最左前缀。如果是这样的,不用增加索引,因为已经有了(例如,如果你在state、city和zip上建立了索引,那么没有必要再增加state的索引)。

    四、通过实例理解单例索引、多列索引以及最左前缀原则

          实例:现在我们想查出满足以下条件的用户id:
          mysql>SELECT `uid` FROM people WHERE lname`='Liu'  AND `fname`='Zhiqun' AND `age`=26 ; 因为我们不想扫描整表,故考虑用索引。

           1、单列索引:
           ALTER TABLE people ADD INDEX lname (lname);
         将lname列建索引,这样就把范围限制在lname='Liu'的结果集1上,之后扫描结果集1,产生满足fname='Zhiqun'的结果集2,再扫描结果集2,找到 age=26的结果集3,即最终结果。

          由于建立了lname列的索引,与执行表的完全扫描相比,效率提高了很多,但我们要求扫描的记录数量仍旧远远超过了实际所需 要的。虽然我们可以删除lname列上的索引,再创建fname或者age 列的索引,但是,不论在哪个列上创建索引搜索效率仍旧相似。

         2、多列索引:
         ALTER TABLE people ADD INDEX lname_fname_age (lame,fname,age);

         为了提高搜索效率,我们需要考虑运用多列索引,由于索引文件以B-Tree格式保存,所以我们不用扫描任何记录,即可得到最终结果。

         注:在mysql中执行查询时,只能使用一个索引,如果我们在lname,fname,age上分别建索引,执行查询时,只能使用一个索引,mysql会选择一个最严格(获得结果集记录数最少)的索引。

         3.最左前缀:顾名思义,就是最左优先,上例中我们创建了lname_fname_age多列索引,相当于创建了(lname)单列索引,(lname,fname)组合索引以及(lname,fname,age)组合索引。

         注:在创建多列索引时,要根据业务需求,where子句中使用最频繁的一列放在最左边。

    一、简介     

           数据库的索引可以加快查询速度,原因是索引使用特定的数据结构(B-Tree)对特定的列额外组织存放,加快存储引擎(索引是存储引擎实现)查找记录的速度。
           索引优化是数据库优化的最重要手段。

           如果查询语句使用索引(通常是where条件匹配索引)就会利用树的结构加快查找,索引会按值查找到要查找的行在表中位置,不需回表查询数据的就是聚簇索引(索引和数据存放在一起)。通常是需要回表再查数据,需要消耗额外的磁盘IO。所以有些时候(如按顺序读取数据)全表扫描会比使用索引快的原因就在于此。

           查询条件只有一个字段时,在该字段建立索引即可,可优化的地方是对于text blob字段使用前缀索引。

           当查询条件有多个字段时,单列索引和多列索引有很大的区别。如果使用多列索引,where条件中字段的顺序非常重要,需要满足最左前缀列。最左前缀:查询条件中的所有字段需要从左边起按顺序出现在多列索引中,查询条件的字段数要小于等于多列索引的字段数,中间字段不能存在范围查询的字段(<,like等),这样的sql可以使用该多列索引。

  • 相关阅读:
    从留言簿开始,学习MonoRail MVC(三)
    从留言簿开始,学习MonoRail MVC(二)
    程序集版本最后一位使用SVN版本号的自动生成方法
    如何让.Net控件在设计时InitializeComponent()中不生成相关代码
    [收藏]Web Services and C# Enums
    从留言簿开始,学习MonoRail MVC(一)
    .Net控制USB设备相关内容
    .Net 2.0ListView控件在Windows 2000和Windows XP上的差异
    基于高德地图Windows Phone API 快速开发地图相关APP(二)
    android map api v2 示例 步骤及问题
  • 原文地址:https://www.cnblogs.com/aspirant/p/7157125.html
Copyright © 2011-2022 走看看