MySQL中的最左匹配原则

 更新时间:2023年09月05日 14:28:22   作者:Blue Protocol  
这篇文章主要介绍了MySQL中的最左匹配原则,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

说明

说到最左匹配原则,我们还得先从组合索引说起。

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(5) NOT NULL AUTO_INCREMENT COMMENT '用户id',
  `username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',
  `password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户密码',
  `create_essay` int(5) NOT NULL COMMENT '原创文章',
  `user_visited` int(10) NOT NULL COMMENT '被访问量',
  `user_rank` int(5) NOT NULL COMMENT '用户排名',
  `perms` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `nickname` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户昵称',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 116856 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
// 创建组合索引
ALTER TABLE `user` ADD INDEX idx_username_password_user_rank (`username`,`password`,`user_rank`)

我们在创建索引的时候,如果我们只选一列,那就叫单列索引,而如果我们选择多列,那么就是组合索引。

在上表中我们创建了一个组合索引:idx_username_password_user_rank( username , password , user_rank )

一般我们组合索引字段数量不建议超过5个,而我们需要理解组合索引的最左匹配原则,我们就可以避免重复创建索引。

比如我们建立了(x,y,z)索引,我们就不需要建立(x)索引,(x,y)索引,因为我们建立(x,y,z)索引就相当于建立了(x)索引,(x,y)组合索引,(x,y,z)组合索引。  

最左匹配原则

什么是最左匹配原则?

然后我们在建立索引的时候,还需要遵循一个规范,就是最左匹配原则,也就是带头大哥在不在的问题。

在写查询条件的时候,我们一定要遵循最左匹配原则,只要大哥不在,索引就会失效了。

比如:

我们创建了一个组合索引叫 idx_username_password_user_rank ( username , password , user_rank )

如果我们在查询过程中,我们这样写

select * from table where password= “xxx” and user_rank = 1

我们这个查询语句是不会命中索引的,因为带头大哥不在,所以索引失效。

也就是我们不能使用空中楼阁,我们把我们的 username当成1楼,password当成2楼,user_rank当成3楼,1楼都不在,我们怎么上2、3楼,这就是最左匹配原则,第一个根本就没有匹配到,后面的就根本不用看了。  

为什么会有最左匹配原则?

要想知道为什么会在组合索引中有最左匹配原则,我们得先理解索引的本质。

我们知道索引的本质是一颗B+Tree,所以组合索引的本质也是一颗B+Tree,不同的是组合索引的键值的数量不是1,而是>=2。

又因为构建一颗B+Tree只能根据一个值来确定索引关系,所以MySQL根据组合索引的最左字段来构建B+Tree。

我们来举一个例子。我们创建一个(a,b)的组合索引,这个组合索引会创建两颗索引树(a),(a,b),而(a,b)的索引树就是下面这个样子的。

在这里插入图片描述

我们可以看到a的值是天然有序的1、 1、 2、 2、 3、 3,而b的值是没有顺序的1、 2、 1、 4、 1、 2。

但是我们在a值一定的情况下,b的值又是顺序排列的,但是这种顺序排列是相对于a来说的。

所以最左匹配原则是因为 MySQL创建组合索引树的规则是首先对组合索引最左边第一个字段进行排序,然后在第一个字段排序的基础上,再对第二个字段进行排序。

所以b=2这种查询条件用不到这两颗联合索引树。

实例说明

针对联合索引,是否遵循最左匹配原则;

建立一个组合索引

idx_username_password_user_rank(`username`,`password`,`user_rank`)
// 命中索引跟顺序无关
explain SELECT * from `user` where username =  "liuxiangcheng" and password = "515239" and user_rank = 1
explain SELECT * from `user` where user_rank = 1 and username =  "liuxiangcheng" and password = "515239"  
explain SELECT * from `user` where user_rank = 1 and password = "515239" and username =  "liuxiangcheng"

结果:

在这里插入图片描述

去掉大哥,看看索引是否命中;

// 去掉大哥
explain SELECT * from `user` where   password = "515239" and user_rank = 1

去掉大哥之后,索引失效,全表扫描。

在这里插入图片描述

MySQL索引命中与失效

查看MySQL索引命中与失效具体见我另一篇博客:MySQL索引命中与失效

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • JDBC链接mysql插入数据后显示问号的原因及解决办法

    JDBC链接mysql插入数据后显示问号的原因及解决办法

    这篇文章主要介绍了JDBC链接mysql插入数据后显示问号的原因及解决办法的相关资料,需要的朋友可以参考下
    2016-04-04
  • mysql 5.7.20解压版安装方法步骤详解(两种方法)

    mysql 5.7.20解压版安装方法步骤详解(两种方法)

    本文给大家分享mysql 5.7.20解压版安装方法步骤详解,本文给大家分享两种方法,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-11-11
  • SQL中"1=1"的陷阱:为什么应避免使用

    SQL中"1=1"的陷阱:为什么应避免使用

    "1=1"在SQL中可能看似无害,但它却是一个隐藏的陷阱,这个简单的表达式可能会导致你的查询结果出现偏差,甚至可能引发安全问题,本指南将揭示这个陷阱,教你如何避免使用"1=1",让你的数据库操作更加安全、准确,让我们一起揭开"1=1"的秘密,提升你的SQL技能!
    2024-02-02
  • SQL索引失效的11种情况详析

    SQL索引失效的11种情况详析

    索引并不是时时都会生效的,遇到一些情况将导致索引失效,下面这篇文章主要给大家介绍了关于SQL索引失效的11种情况,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-03-03
  • Mysql数据库增量备份的思路和方法

    Mysql数据库增量备份的思路和方法

    MySQL数据库增量备份,在这之前修改我们的数据库配置文件/etc/my.cnf开启bin-log日志功能即可,下面小编给大家分享Mysql数据库增量备份的思路详解,一起看看吧
    2017-09-09
  • MySql完整卸载的四个步骤详解

    MySql完整卸载的四个步骤详解

    有时候MySQL不能完全卸载,这时候必须通过一些途径删除掉注册表和一些残余的文件,然后才能重新安装才可以成功,下面这篇文章主要给大家介绍了关于MySql完整卸载的四个步骤,需要的朋友可以参考下
    2022-06-06
  • 详解mysql慢日志查询

    详解mysql慢日志查询

    这篇文章主要介绍了mysql慢日志查询的相关资料,帮助大家更好的理解和使用MySQL数据库,感兴趣的朋友可以了解下
    2020-09-09
  • MySQL中CONCAT()函数出现值为空的问题及解决办法

    MySQL中CONCAT()函数出现值为空的问题及解决办法

    项目中查询用到了concat()拼接函数,本文主要介绍了MySQL中CONCAT()函数出现值为空的问题及解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-07-07
  • MySQL数据库的一次死锁实例分析

    MySQL数据库的一次死锁实例分析

    本文主要给大家通过一个实例来具体介绍MySQL死锁问题的相关知识,接下来我们就来一一介绍这部分内容,希望能够对您有所帮助。
    2016-11-11
  • MySQL中的LOCATE和POSITION函数使用方法

    MySQL中的LOCATE和POSITION函数使用方法

    不常用:MySQL中的LOCATE和POSITION函数
    2010-02-02

最新评论