• mysql多列索引和最左前缀


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

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

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

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

    MySQL多列索引适合的场景

    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'

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

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

    单列索引:
    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子句中使用最频繁的一列放在最左边。

  • 相关阅读:
    iOS UITableViewCell中包含UICollectionView嵌套 解决UITableViewCell显示异常
    mac 终端创建podfile文件
    iOS UIScrollView弹性问题
    NSMutableParagraphStyle与NSParagraphStyle的使用
    iOS 单个控制器隐藏 导航栏下划线
    iOS UICollectionView reloadData后立即获取contentSize.height高度
    高德地图API开发二三事(一)如何判断点是否在折线上及引申思考
    Python-6
    Python-模块
    python-递归函数和内置函数笔记汇总
  • 原文地址:https://www.cnblogs.com/usa007lhy/p/6442570.html
Copyright © 2020-2023  润新知