我们都知道,当数据表中的数据日益增长后,查询会变得越来越慢,当初在表设计之初,尚未考虑创建索引的话,那么现在正是必要的时候。可是,如果对于MySQL使用索引的策略不了解,或是脱离了具体业务场景,那么,创建出来的索引,也发挥不了多大的作用。本文,就从我刚刚完成的一个项目入手,介绍如何正确的设计联合索引,以在实战项目中真正的发挥作用。

实际的业务场景

下图展示了项目所涉及的实际业务场景:

可以看到,查询条件主要涉及:视频分区、产品类别、产品、视频时长 和 发布时间。

其中,视频分区下,还有子分区:

产品下面,还有所属品牌:

所以,我们可以把查询条件做个梳理:1、视频分区 > 子分区,2、产品类别 > 产品 > 品牌。其中 产品类别产品 会根据用户选择的 视频分区子分区 的不同而变化,这样就会衍生出很多不同的业务逻辑 和 查询条件的组合:

  • 视频分区 > 子分区 > 产品类别 > 产品 > 品牌

这代表了用户既选了视频分区和子分区,同时又基于所属子分区下的产品类别,又选择了产品和品牌,即 所有关键的查询条件都用上了。下面的示意逻辑相同,只是组合不同而已。

  • 视频分区 > 子分区 > 产品类别
  • 视频分区 > 子分区 > 产品 > 品牌
  • 视频分区 > 产品类别 > 产品 > 品牌
  • 视频分区 > 产品类别
  • 视频分区 > 产品 > 品牌
  • 产品类别 > 产品 > 品牌
  • 产品 > 品牌

这里只列举了部分查询条件的组合,其实还有更多。其中特别标注出来的,是在实际使用场景下,常用的查询组合。下面我们就来看一看,如何基于这些查询条件,设计出合理的索引。

基于业务场景的联合索引的设计方案

我们把索引简单的分为 单列索引多列索引,多列索引被称为 联合索引复合索引,对于查询语句中的 where 条件,如果某些条件是这个查询中频繁用到的组合,那么,通常会创建联合索引,来提升查询效率。

但是,对于一个没有深谙其道的人来讲,他可能会这样设计联合索引:

  1. 给每个查询字段创建一个 单列索引

    CREATE INDEX 索引名称 ON 表名 (视频分区);
    CREATE INDEX 索引名称 ON 表名 (子分区);

    ...

  2. 只创建一个能覆盖到所有查询条件的 联合索引

    CREATE INDEX 索引名称 ON 表名 (视频分区, 子分区, 产品类别, 产品, 品牌);

以为这样,就可以让索引发挥全部作用,适用于所有查询条件的组合了。其实,联合索引 有一个最左匹配原则,从左至右匹配你的查询条件,直至断掉终止,如果索引列的第一个字段都尚不能匹配,则用不上此索引。比如:

  • 我们查询 视频分区 > 子分区 > 产品类别 > 产品 > 品牌 这些条件组合,当然可以用到上面创建的索引,因为查询条件与索引列完全对的上。
  • 如果查询 产品类别 > 产品 > 品牌 的话,则索引就无效了,因为索引列的第一个索引字段 视频分区 不在 where 查询条件中,最左匹配原则一开始就失败了,所以用不上索引。
  • 如果查询 视频分区 > 子分区,这是符合最左匹配原则的【英文叫 leftmost prefix of the index】,这个 leftmost 就告诉我们,虽然索引列并不完全匹配查询条件,但是部分匹配,而且必须顶着头的、排着队的、中间没有断掉的匹配了,即使尾巴断掉了没有关系,依然可以用上此索引。
  • 最后,如果查询 视频分区 > 子分区 + 发布时间 这组条件,能否用的上此索引呢?答案是肯定的,我不管你 where 条件中,哪些列不是索引列,我只关心你 where 条件中,哪些列在索引列之中,并且符合最左匹配就行了。

好了,到这里,我们应该逐渐清楚的认识到,仅仅创建一个包含所有查询条件的联合索引 视频分区, 子分区, 产品类别, 产品, 品牌 是远远不够的,而是需要根据业务需求和使用场景,将可能会频繁用到的查询条件,进行不同的排列组合,设计出一个折中的 联合索引 的方案。

正如你在本文前一部分看到的,在我列举出的部分查询条件中,着重标注出来的那些,就是我认为会最频繁使用到的组合,所以,需要相应的创建多个不同组合的 联合索引,以此来应对前端操作用户选择不同查询条件时,能够最大限度的命中索引,提升查询效率。

索引无法解决的问题

你应该也能看得出来,即使合理的创建了 联合索引,也无法覆盖到全部的查询条件的各种组合。好吧,就算你真的根据所有的组合,都相应的创建了 联合索引,但还有最后一关你过不去,那就是 模糊查询。你注意到,我的项目中,用到了根据用户输入的内容,来进行搜索,这必然需要使用模糊查询来实现,但是,%xxx% 这种形式的模糊查询,是无论如何也用不上索引的。

针对以上问题,我突发奇想,想到了一个绝妙的方案,并加以实施,应用到了我的项目中,结果效果非常好。在下一篇,我再作具体介绍。

MySQL联合索引的排列组合应用实战的更多相关文章

  1. 三道MySQL联合索引面试题,淘汰80%的面试者,你能答对几道

    众所周知MySQL联合索引遵循最左前缀匹配原则,在少数情况下也会不遵循(有兴趣,可以翻一下上篇文章). 创建联合索引的时候,建议优先把区分度高的字段放在第一列. 至于怎么统计区分度,可以按照下面这种方 ...

  2. MySQL 联合索引详解

    MySQL 联合索引详解   联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分.例如索引是key index (a,b,c ...

  3. mysql 联合索引(转)

    http://blog.csdn.net/lmh12506/article/details/8879916 mysql 联合索引详解 联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中 ...

  4. [转]mysql联合索引

    mysql联合索引   命名规则:表名_字段名1.需要加索引的字段,要在where条件中2.数据量少的字段不需要加索引3.如果where条件中是OR关系,加索引不起作用4.符合最左原则 https:/ ...

  5. SQL Server中的联合主键、聚集索引、非聚集索引、mysql 联合索引

    我们都知道在一个表中当需要2列以上才能确定记录的唯一性的时候,就需要用到联合主键,当建立联合主键以后,在查询数据的时候性能就会有很大的提升,不过并不是对联合主键的任何列单独查询的时候性能都会提升,但我 ...

  6. MySQL联合索引VS单列索引

    MySQL联合索引VS单列索引 以一个一千万数据量的表格为例 1. 建表建索引 USE foo; DROP TABLE IF EXISTS tmp; CREATE TABLE tmp ( id INT ...

  7. MySQL联合索引最左匹配范例

    MySQL联合索引最左匹配范例 参考文章:http://blog.jobbole.com/24006/ 创建示例表. 示例表来自MySQL官方文档: https://dev.mysql.com/doc ...

  8. 我说MySQL联合索引遵循最左前缀匹配原则,面试官让我回去等通知

    面试官: 我看你的简历上写着精通MySQL,问你个简单的问题,MySQL联合索引有什么特性? 心想,这还不简单,这不是问到我手心里了吗? 听我给你背一遍八股文! 我: MySQL联合索引遵循最左前缀匹 ...

  9. mysql联合索引详解

    联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索 引中的一部份,但只能是最左侧部分.例如索引是key index (a,b,c). 可以支持a | a,b ...

随机推荐

  1. NX7.5 使用UF_MODL_create_proj_curves创建投影曲线

    1 [DllImport("libufun.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet ...

  2. SyntaxError: Non-UTF-8 code starting with '\xbb' in file D:\流畅学python\ex32.py on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

    1. 报错如下: SyntaxError: Non-UTF-8 code starting with '\xd3' in file D:\流畅学python\ex34.py on line 4, bu ...

  3. mongodb的索引操作

    在mongodb中,当我们一个集合中的数据量非常大时,比如几百万条数据,如果不使用索引,对数据的查询就会进行全表扫描,这个时候查询的速度就会非常的慢,此时我们就需要为集合建立上索引,从而加快查询的速度 ...

  4. camera isp(Image Signal Processor)

    1. 目标[52RD.com] 手机摄像头模组用ISP功能模块的市场走向及研发方向.为能够正确认识手机摄像模组行业提供技术及市场依据.[52RD.com] 2. ISP在模组上的应用原理[52RD.c ...

  5. STM32中按键中断分析

    在按键学习中,我们有用到查询的方法来判断按键事件是否发生,这种查询按键事件适用于程序工作量较少的情况下,一旦程序中工作量较大较多,则势必影响程序运行的效率,为了简化程序中控制的功能模块的执行时间,引入 ...

  6. 深入理解Linux C语言内存管理

    问题不能拖,我这就来学习一下吧,争取一次搞定. 在任何程序设计环境及语言中,内存管理都十分重要. 内存管理的基本概念 分析C语言内存的分布先从Linux下可执行的C程序入手.现在有一个简单的C源程序h ...

  7. 洛谷 P3147 [USACO16OPEN]262144 P

    链接: P3147 P3146双倍经验 前言: 今天发现的一道很有意思的DP题 分析: 第一眼以为是区间DP,于是设f[i][j]为从第i个数到第j个数可以合出的最大值,但思考后发现并不能简单合并,并 ...

  8. Python AttributeError: module 'sys' has no attribute 'setdefaultencoding'

    Python 3 与 Python 2 有很大的区别,其中Python 3 系统默认使用的就是utf-8编码. 所以,对于使用的是Python 3 的情况,就不需要sys.setdefaultenco ...

  9. DeWeb 电脑和手机动态适配

    DeWeb 做多平台适配很方便! 多平台适配代码在OnMouseUp中. X,Y分别表示当前设备的Width/Height: Button : mbLeft : 屏幕纵向, mbRight:屏幕横向: ...

  10. Awesome metaverse projects (元宇宙精选资源汇总)

    Awesome Metaverse 关于 Metaverse 的精彩项目和信息资源列表. 由于关于 Metaverse 是什么存在许多相互竞争的想法,请随时以拉取请求.问题和评论的形式留下反馈. We ...