Mysql 联合索引

article/2025/10/13 9:06:11

联合索引底层数据结构

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

    例如建立了一个(‘name’,‘age’,‘position’)三个列的联合索引,那么非叶子节点中就存储了name,age,position字段,排序的时候先根据第一个字段name来排序,再按第二个字段age排序,再按position字段排序。从左往右,name为H开头的肯定排在b开头的数据后面,name相同的情况下,age=10的肯定排在age=9的后面,以此类推。
在这里插入图片描述
那么根据此图,我们就能很好理解联合索引的最左前缀原则了。
以上图为例。 我创建了一个示例表:

CREATE TABLE `test_index` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`age` int(11) DEFAULT NULL,`position` varchar(255) DEFAULT NULL,`update_time` datetime DEFAULT NULL,PRIMARY KEY (`id`),KEY `idx_name_age_position` (`name`,`age`,`position`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
并且已经创建了索引 `idx_name_age_position` (`name`,`age`,`position`) 

索引长度计算方法

计算规则
1.索引字段,没有设置NOT NULL,需要占用一个字节。NULL在mysql中是用一个标志位来表示的,用一个字节,null也走索引,并且排在索引的最前面。并不是有些说法说的那样不走索引的
2.定长字段:tinyiny占1个字节、int占4个字节、bitint占8个字节、date占3个字节、datetime占5个字节,char(n)占n个字符。
3.变长字段:varchar(n)占n个字符+2个字节。
4.不同的字符集,一个字符占用的字节数不同:

latin1编码,每个字符占用一个字节
gbk编码,每个字符占用两个字节
utf8编码,每个字符占用三个字节
utf8mb4编码,每个字符占用四个字节

像上面的例子,我用的是utf8编码,并且没有设置不可为null。
name索引长度: 2553+2+1=768 (null标志位占一个字节)
age索引长度:4+1=5 (null标志位占一个字节)
position索引长度: 255
3+2+1=768 (null标志位占一个字节)

联合索引示例

.

  1. explain select * from t where name=‘Bill’ and age=40 and position=‘dev’
    在这里插入图片描述
    走索引的,并且可以看到索引长度为1541,768+768+5=1541,正好对的上,说明走了这个索引的全部字段。
    我如果把name列改为不可为Null(具体过程就不写了),再来看一下
    在这里插入图片描述
    key_len变成1540了,说明 null 确实占一个字节。这里只为说明 null 占一个字节,后续的示例都是可以为null情况的。
  2. explain SELECT * FROM test_index where name=‘Bill’ and age>30;
    在这里插入图片描述
    走索引,并且索引长度为773(768+5)说明走了索引的name,age字段
  3. explain SELECT * FROM test_index where name=‘Bill’ and age>30 and position = ‘dev’;. 在这里插入图片描述
    走索引,只走了索引的name,age字段,position字段没走。可以看到索引长度为773(768+5)
    确实走不了position字段这部分,age是一个范围查找,定位到age=30之后,可以根据索引找到>30的记录,但是position索引没法用啊,你不能说age=Bill,age=30,position=dev这条记录的数据右边都是满足条件的,age=31,position=aaa 也是在它右边,是不满足查询要求的。只能对前两个字段用索引
  4. explain SELECT * FROM test_index where name=‘Bill’ and position = ‘dev’;
    在这里插入图片描述
    走索引,只走了索引的name字段部分,position字段没走,可以看到索引长度为768
  5. explain SELECT * FROM test_index where name=‘Bill’ and position > ‘dev’;. 在这里插入图片描述
    走索引,只走了索引的name字段部分,position字段没走,可以看到索引长度为768
  6. explain SELECT * FROM test_index where age=30 and position = ‘dev’;
    在这里插入图片描述
    不走索引,因为第一列没被引用,那么要想找到 age=30 and position = 'dev’的记录,只能把索引全部扫描一遍,再通过回表去找到对应记录,那还不如全表扫描。
  7. explain SELECT * FROM test_index where name>‘Bill’ and age=30 and position = ‘dev’; 在这里插入图片描述
    走索引,只走了索引的name字段部分,age 和 position字段没走,可以看到索引长度为768
    name是范围查找,可以走name那一部分索引

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

相关文章

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&…

jedis介绍

jedis是redis的java版本的客户端实现。下面演示jedis的相关操作&#xff1a;      首先在eclipse新建动态web工程&#xff1a;            将jedis所需的jar包导入到工程中&#xff1a;            编写Java代码测试连通性&#xff1a; import …

jedis相关详解

一、jedis是什么&#xff1f; Jedis是redis的java版本的客户端实现&#xff0c;使用Jedis提供的Java API对Redis进行操作&#xff0c;是Redis官方推崇的方式&#xff1b;并且&#xff0c;使用Jedis提供的对Redis的支持也最为灵活、全面&#xff1b;不足之处&#xff0c;就是编…

Redis 客户端:Jredis 和 spring-data-redis 整合

因为我使用的是 java &#xff0c;所以我学习的是java 的客户端 &#xff1a;Jredis 。整合结合自己的项目&#xff0c;把 Jredis 的客户端整合一下。 我们整合需要的工具&#xff1a; Redis Serviceredis.clients.jedis 2.9.0 &#xff08;java 客户端链接redis&#xff09;…

Redis使用教程(一)

Redis:单线程、高读写 redis数据库初识 Redis 简介 Redis 的安装配置 Redis 的常见操作 Redis 的数据类型 Redis 的事务控制 Java 操作 Redis 数据库 Redis简介 redis的作用 Redis:REmote DIctionary Server( 远程字典服务器 ) 是完全开源免费的&#xff0c;用 C 语言编写的…