mysql 联合索引结构与索引匹配原则

article/2025/10/13 8:32:05

联合索引结构与索引匹配原则

最左前缀匹配原则:在MySQL建立联合索引时会遵守最左前缀匹配原则,即最左优先,在检索数据时从联合索引的最左边开始匹配。

要想理解联合索引的最左匹配原则,先来理解下索引的底层原理。索引的底层是一棵B+树,那么联合索引的底层也就一棵B+树,只不过联合索引的B+树节点中储存的是键值。由于构建一棵B+树只能根据一个值来确定索引关系,所以数据库依赖联合索引最左的字段来构建。

举例:创建一个(A,B)的联合索引,那么它的索引树就是下图的样子。

在这里插入图片描述
可以看到A的值是有序的 1,1,2,2,3,3,而B的值是没有顺序的1,2,1,4,1,2 。但是我们又能发现A在等值的情况下,B值又是按顺序排列的,但是这种顺序是相对的。这是因为MySQL创建联合索引的规则是首先会对联合索引的最左边第一个字段排序,在第一个字段的排序基础上,然后再对第二个字段进行排序。所以B=2这种查询条件没有办法利用索引。

示例:

表结构:

字段类型描述
idint(11)主键
namevarchar(10)名称
ageint(11)年龄
sexint(10)性别

该表中id列,name列,age列建立了一个联合索引 idx_name_age_sex ,实际上相当于建立了三个索引:(name)(name_age)(name_age_sex)


建立索引:alter table staffs add index idx_name_age_sex(name,age,sex);


下面介绍下可能会使用到该索引的几种情况:

1. 全值匹配查询

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过观察上面的结果图可知,where后面的查询条件,无论是使用(name,age,sex)(age,name,sex)(sex,age,name)顺序,在查询时都使用到了联合索引。可能有人会疑惑,为什么底下两个的搜索条件明明没有按照联合索引从左到右进行匹配,却也使用到了联合索引? 这是因为MySQL中有查询优化器explain,所以sql语句中字段的顺序不需要和联合索引定义的字段顺序相同,查询优化器会判断纠正这条sql语句以什么样的顺序执行效率高,最后才能生成真正的执行计划,所以无论以何种顺序都可以使用到联合索引。

2. 匹配最左边列时

在这里插入图片描述
该搜索是遵守最左匹配原则的,通过key字段可知,在搜索过程中使用到了联合索引,且使用的是联合索引中的(name)索引。

在这里插入图片描述
由于name到age是从左依次往右边匹配,这两个字段中的值都是有序的,所以也遵守最左匹配原则,通过key字段可知,在搜索过程中也使用到了联合索引,但使用的是联合索引中的(name_age)索引。

在这里插入图片描述
由于上面三个搜索都是从左边name依次向右开始匹配的,所以都用到了(name_age_sex)联合索引。

那如果不是依次匹配呢?

在这里插入图片描述
通过key字段可知,在搜索过程中也使用到了联合索引,但使用的是联合索引中的(name)索引,因为联合索引树是按照name字段创建的,但sex相对于name来说是无序的,只有name是有序的,所以他只能使用联合索引中的name索引。

在这里插入图片描述
通过观察发现上面key字段在搜索中也使用了(name_age_sex)索引,可能大家就会有疑惑,它并没有遵守最左匹配原则,按道理会索引失效,为什么也使用到了联合索引? 因为没有从name开始匹配,且age单独来说是无序的,所以它确实不遵守最左匹配原则,然而从type字段可知,它虽然使用了联合索引,但是它是对整个索引树进行了扫描,正好匹配到了该索引,与最左匹配原则无关,一般只要是某联合索引的一部分,但又不遵守最左匹配原则时,都可能会采用index类型的方式扫描,但它的效率远不如最左匹配原则的查询效率高,index类型的扫描方式是从索引的第一个字段一个一个的查找,直到找到符合的某个索引,与all不同的是,index是对所有索引树进行扫描,而all是对整个磁盘的数据进行全表扫描。

在这里插入图片描述
在这里插入图片描述
这两个结果跟上面的是同样的道理,由于它们没有从最左边开始匹配,所以没有用到联合索引,而是使用了index类型进行全索引扫描。

3. LIKE 模糊查询

对于模糊匹配的查询,如果是前缀匹配的是索引,中缀和后缀用的是全索引扫描。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


http://chatgpt.dhexx.cn/article/rvETqQdb.shtml

相关文章

详解MySQL联合索引

引言 本文预计分为两个部分:(1)联合索引部分的基础知识 在这个部分,我们温习一下联合索引的基础(2)联合索引部分的实战题 在这个部分,列举几个我认为算是实战中的代表题,挑出来说说。 正文 基础 讲联合索引,一定要扯最左匹配!…

mysql联合索引的使用

这篇笔记主要记录联合索引的使用 设置了shopId、userId、relationId三个字段,作为联合索引,这三个字段,都是long类型的,也就是bigint 分别验证以下几个场景: 场景一:explain select * from testIndex wher…

MySQL联合索引的原理

面试中被问到了联合索引,突然就涉及到了知识盲区,对不起,我只知道B树,B树,哈希索引,聚簇索引,非聚簇索引,联合索引的原理?。。 对不起涉及到了我的知识盲区了。 这里对联…

Mysql 联合索引

联合索引底层数据结构 MySQL可以使用多个字段同时建立一个索引,叫做联合索引。上文中讲到索引的底层结构就是一个二叉树,联合索引也是一样,它的非叶子节点中存的就不只是一个列,是索引的所有列,并且它的排序就是根据索引列的先后顺…

mysql联合索引详解

比较简单的是单列索引(btree)。遇到多条件查询时,不可避免会使用到多列索引。联合索引又叫复合索引。 btree结构如下: 每一个磁盘块在mysql中是一个页,页大小是固定的,mysql innodb的默认的页大小是16k&a…

MySQL索引详解

本文主要介绍MySQL索引底层原理及优化,理解SQL是如何执行,MySQL如何选择合适的索引以及时间都消耗在哪些地方,再加上一些优化的知识,可以帮助大家更好的理解MySQL,理解常见优化技巧背后的原理。希望本文中的原理、示例…

MySQL索引之联合索引

目录 1. 联合索引1.1. 联合索引的存储结构1.2. 联合索引的查询流程1.3. 最左前缀匹配原则1.3.1. 最左前缀匹配原则说明 2. 索引下推2.1. 无索引下推的执行流程2.2. 有索引下推的执行流程 1. 联合索引 在平时开发中,我们最常见的是聚集索引,但在我们需要…

jedis和redisTemplate

使用原生jedis和spring的redisTemplate调用连接池,发现差别巨大: redis配置: redis:database: 0host: 127.0.0.1port: 6379password: 123456timeout: 5000lettuce:shutdown-timeout: 200pool:max-active: 500max-idle: 100min-idle: 50max-w…

16.Jedis

目录 一、Jedis知识点总览。 二、连接池配置&#xff1a; 三、测试类&#xff1a; 一、Jedis知识点总览。 public class ProvinceServiceImpl implements ProvinceService {private ProvinceDao dao new ProvinceDaoImpl();Overridepublic List<Province> findAll(…

Jedis的配置和使用

什么是jedis 是官方推荐的java连接开发工具&#xff0c;使用java操作Redis的中间件&#xff0c;如果要使用java操作redis&#xff0c;那么要对jedis十分熟悉 测试 导入对应的依赖(Jedis和fastjson)&#xff1a; <dependencies><dependency><groupId>redi…

Jredis操作redis的入门级例子

redis入门级例子&#xff1a; Java代码 package com.liuxinglanyue.test; import java.util.ArrayList; import java.util.List; import org.jredis.JRedis; import org.jredis.RedisException; import org.jredis.ri.alphazero.JRedisClient; import org.…

jedis入门

目录 一、Jedis 1.Jedis简介 2.导包 3.官方文档 4.常用API 5.基本操作 6.jedis连接池的使用 7.工具类的编写 8.简单的使用 9.JedisPoolConfig的配置参数 一、Jedis 1.Jedis简介 Redis不仅是使用命令来操作&#xff0c;现在基本上主流的语言都有客户端支持&#xf…

Jedis的简单使用

Jedis的简单使用 创建连接操作key操作string操作list操作set操作zset操作hashJedis连接池工具类 创建连接 public static Jedis jedis null;static {// 地址 和 端口jedis new Jedis("127.0.0.1", 6379);// jedis.auth("helloworld"); // 若你的redis设…

【国产开源】兼容redis协议的内存数据库

背景 jredis是一个高性能、高可用、低延迟的内存数据库&#xff0c;服务端源码请移步这里 编写目的 加深对底层网络传输&#xff0c;文件存储&#xff0c;文件索引的认知&#xff0c;同时也巩固自身的知识点。 协议特征 兼容redis原生协议 set get lpush rpush lrange blp…

Jedis 入门

Jedis官网快速跳转 Jedis 的 Github 官方网站跳转&#xff1a;redis/jedis 1. Jedis的基本使用 1.1 引入Jedis依赖 <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>4.2.3</version> </d…

Redis Java客户端Jredis

JRedis 是一个高性能的 Java 客户端&#xff0c;用来连接到Redis分布式哈希键-值数据库。提供同步和异步的连接。 项目地址&#xff1a;https://github.com/alphazero/jredis 由于jreds的jar包不在公网的maven仓库中&#xff0c;所以需要下载源码使用如下命令&#xff0c;将j…

4.jedis

1.pom依赖 <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.9.0</version> </dependency>2.客户端连接redis

JDK: JRE

序言 这个跟类加载有关. 其它的没啥好说的,直接说重点吧 重点 我们安装JDK后会有两个目录一个是JDK,一个是JRE.如下图所示: JDK: 这个是我们开发时需要往Eclipse或者Idear中引入的,里面主要包含了编译器,即把Java文件编译成Class文件的相关Jar.以及开发的过程所需要的一些工…

Jedis详解

因为工作的需要&#xff0c;底层同事对Redis进行了部分改造&#xff0c;增加了几个命令&#xff0c;对应着也就需要对Jedis进行部分修改&#xff0c;于是就把Jedis相关的代码读了一遍&#xff0c;发现其设计还是非常简单但又巧妙使用。 通常而言&#xff0c;我们对于Redis集群…

Jedis简介

Jedis用于java语言连接redis服务&#xff0c;并提供对应的操作API 一、准备工作 (1)jar包导入 下载地址&#xff1a;https://mvnrepository.com/artifact/redis.clients/jedis 基于maven <dependency> <groupId>redis.clients</groupId> <artifactId&…