联合索引失效情况分析

一.模拟表结构:

背景:

MySQL版本——8.0.37

表结构DDL:

CREATE TABLE `unite_index_table` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',`clomn_first` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '列1',`clomn_second` bigint NOT NULL COMMENT '列2',`clomn_third` bigint NOT NULL COMMENT '列3',`clomn_fourth` int NOT NULL COMMENT '列4',`clomn_fifth` bigint NOT NULL COMMENT '列5',`clomn_sixth` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '列6',`clomn_seventh` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '列7',`clomn_eighth` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '列8',`clomn_ninth` int NOT NULL COMMENT '列9',`clomn_tenth` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '列10',`clomn_eleventh` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '列11',`clomn_twelfth` bigint NOT NULL COMMENT '列12',`clomn_thirteenth` bigint NOT NULL COMMENT '列13',`clomn_fourteenth` bigint NOT NULL COMMENT '列14',`clomn_fifteenth` tinyint NOT NULL DEFAULT '1' COMMENT '列15',PRIMARY KEY (`id`),KEY `idx_clomn_fifth` (`clomn_fifth`),KEY `idx_unite` (`clomn_second`,`clomn_third`,`clomn_twelfth`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='模拟表';

表结构比较奇怪,是为了模拟实际生产的表结构,表结构信息进行脱敏;

 创建mock数据:
 

DROP PROCEDURE
IFEXISTS generate_mock_data;DELIMITER //
CREATE PROCEDURE generate_mock_data ( IN row_count INT ) BEGINDECLAREi INT DEFAULT 0;START TRANSACTION;-- 开始事务WHILEi < row_count DOINSERT INTO unite_index_table (clomn_first,clomn_second,clomn_third,clomn_fourth,clomn_fifth,clomn_sixth,clomn_seventh,clomn_eighth,clomn_ninth,clomn_tenth,clomn_eleventh,clomn_twelfth,clomn_thirteenth,clomn_fourteenth,clomn_fifteenth )VALUES(SUBSTRING( MD5( RAND( ) ), 1, 20 ),FLOOR( RAND( ) * 10000000000 ),FLOOR( RAND( ) * 10000000000 ),FLOOR( RAND( ) * 100000 ),FLOOR( RAND( ) * 10000000000 ),SUBSTRING( MD5( RAND( ) ), 1, 64 ),IF( RAND( ) > 0.5, SUBSTRING( MD5( RAND( ) ), 1, 64 ), NULL ),IF( RAND( ) > 0.5, SUBSTRING( MD5( RAND( ) ), 1, 20 ), NULL ),FLOOR( RAND( ) * 256 ),IF( RAND( ) > 0.5, SUBSTRING( MD5( RAND( ) ), 1, 1024 ), NULL ),IF( RAND( ) > 0.5, SUBSTRING( MD5( RAND( ) ), 1, 64 ), NULL ),FLOOR( RAND( ) * 10000000000 ),UNIX_TIMESTAMP( ),UNIX_TIMESTAMP( ),FLOOR( RAND( ) * 2 ) );SET i = i + 1;END WHILE;COMMIT;-- 提交事务END // 
DELIMITER;
CALL generate_mock_data ( 1000000 );
DROP PROCEDURE
IFEXISTS generate_mock_data;

 二.不同情况下的查询:

背景补充:

1.做模拟查询的时候,如果使用区间查询(>,>=,<,<=,!=,between and),区间查询的值需要再表中存在,而不是超出区间,不然可能会导致explain分析该SQL会使用索引(实则为查询值越界)

补充:

摘自MySQL官网
key_len (JSON name: key_length)

The key_len column indicates the length of the key that MySQL decided to use. The value of key_len enables you to determine how many parts of a multiple-part key MySQL actually uses. If the key column says NULL, the key_len column also says NULL.

Due to the key storage format, the key length is one greater for a column that can be NULL than for a NOT NULL column.

2.key_len 的计算基于索引中每列的数据类型、字符集以及是否允许 NULL。以下是一些常见数据类型的索引长度:

  • INT:4 字节。
  • BIGINT:8 字节。
  • VARCHAR(n):根据字符集计算。例如,utf8mb4 字符集下,VARCHAR(20) 可能占用 n * 4 字节(utf8mb4 每个字符最多 4 字节)。
  • CHAR(n):与 VARCHAR 类似,但 CHAR 是固定长度。
  • 如果列允许 NULL,则会额外增加 1 字节(用于存储 NULL 标志)。

在联合索引中,key_len 是查询中实际用到的索引列的长度之和。MySQL 会根据查询条件和最左匹配原则,决定使用索引的前几列。

key_len展示所使用到的索引key的长度,会根据具体使用到的索引的联合索引的key个数以及索引列的类型发生变化;

例如:

仅使用首列索引;
 使用所有索引列;

能使用到索引的情况:

1.使用索引的首列等值查询和第三列区间查询:

EXPLAIN SELECT* 
FROMunite_index_table 
WHEREclomn_twelfth >= 7827883584 AND clomn_second = 2058342613
SQL Explain
idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEunite_index_tablerefidx_uniteidx_unite8const57433.33Using index condition

 分析得出,因为使用了联合索引的第一列,所以查询是使用到了索引,具体使用情况为:Using index condition

联合索引哪怕是仅用到了索引首列,也是可以走索引优化查询(另外提一嘴,是否走联合索引和where条件后的列先后顺序无关,最左匹配和查询时列索引顺序毫无关系,MySQL对SQL会进行解释器优化);

2.使用索引首列等值查询,第二列区间查询,第三列区间查询

EXPLAIN SELECT* 
FROMunite_index_table 
WHEREclomn_twelfth != 3665470530 AND clomn_second = 6132267663 AND clomn_third >= 845697131
idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEunite_index_tablerangeidx_uniteidx_unite16190Using index condition

使用到了索引,key_len为16,表名使用了索引的首列和次列;

补充说明:

//将clomn_second全部设置为1,让索引列失去特异性,验证第一种情况是否仍然成立:

EXPLAIN SELECT* 
FROMunite_index_table 
WHEREclomn_twelfth >= 7827883584 AND clomn_second = 1
idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEunite_index_tablerefidx_uniteidx_unite8const30421633.33Using index condition

 虽然索引失去了特异性,仍然使用了索引,但是此时的key_len变成了8;

//再将clomn_third全部设置为2,让索引列失去特异性,验证第二种情况是否仍然成立:

EXPLAIN SELECT* 
FROMunite_index_table 
WHEREclomn_twelfth != 3665470530 AND clomn_second = 1 AND clomn_third = 2
idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEunite_index_tableALLidx_unite606845100Using where

 出乎意料的,联合索引第一列索引和第二列索引列同时失去特异性后,导致查询不能够走到索引,造成全表扫描

不能使用到索引的情况:

1.索引第一列为区域查询(带有>或者<),不包含其他列

EXPLAIN SELECT* 
FROMunite_index_table 
WHEREclomn_second > 251963017
idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEunite_index_tableALLidx_unite61074250Using where

查询仅带有首列的区间查询, 查询不能走联合索引

2.索引第一列为区间查询(带有>或者<)

EXPLAIN SELECT* 
FROMunite_index_table 
WHEREclomn_second > 251963017 AND clomn_third = 5251684771
idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEunite_index_tableALLidx_unite6107425Using where

因为首行非等值查询,而是区间查询,且有其他查询列,联合查询不走索引(上一个示例都不会索引,这个更不会)

3.使用联合索引的第二列和第三列

EXPLAIN SELECT* 
FROMunite_index_table 
WHEREclomn_third = 5251684771 AND clomn_twelfth > 2058342
idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEunite_index_tableALL6107423.33Using where

由于没有筛选首列,联合索引没能走到联合索引的优化,即通常讲的不满足最左匹配原则;

三.总结:

总体结论
  1. 首列等值查询是关键
    • 只要首列(clomn_second)使用等值查询(=),即使后续列使用区间查询(>、>=)或不等值查询(!=),联合索引仍可使用。
  2. 首列区间查询导致索引失效
    • 当首列使用区间查询(>、<等),无论后续列条件如何,联合索引无法使用,导致全表扫描。
  3. 最左匹配原则
    • 联合索引必须从首列开始匹配,跳过首列直接查询后续列无法利用索引。
  4. 特异性影响
    • 首列失去特异性时,索引仍可使用,但性能下降(扫描行数增加)。
    • 首列和后续列均失去特异性时,索引可能失效,导致全表扫描。
  5. 查询条件顺序无关
    • WHERE子句中列的顺序不影响索引使用,MySQL优化器会自动调整。
建议:
  1. 索引设计
    • 将常用等值查询的列放在联合索引的前列,确保满足最左匹配原则。
    • 避免将区间查询列作为索引首列
  2. 特异性优化
    • 确保索引列具有足够的区分度,避免值重复率过高。
    • 定期分析数据分布,调整索引策略。
  3. 查询优化
    • 优先使用等值条件过滤首列数据,再处理范围条件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/83958.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件架构之-论分布式架构设计及其实现

论分布式架构设计及其实现 摘要正文摘要 2023年2月,本人所在集团公司承接了长三角地区某省渔船图纸电子化审查项目开发,该项目旨在为长三角地区渔船建造设计院、渔船审图机构提供一个便捷化的服务平台。在次项目中,我作为项目成员参与了整个项目的建设工作,全权负责项目需求…

Pydantic数据验证实战指南:让Python应用更健壮与智能

导读&#xff1a;在日益复杂的数据驱动开发环境中&#xff0c;如何高效、安全地处理和验证数据成为每位Python开发者面临的关键挑战。本文全面解析了Pydantic这一革命性数据验证库&#xff0c;展示了它如何通过声明式API和类型提示系统&#xff0c;彻底改变Python数据处理模式。…

3、ubantu系统 | 通过vscode远程安装并配置anaconda

1、vscode登录 登录后通过pwd可以发现目前位于wangqinag账号下&#xff0c;左侧为属于该账号的文件夹及文件。 通过cd ..可以回到上一级目录&#xff0c;通过ls可以查看当前目录下的文件夹及文件。 2、安装 2.1、下载anaconda 通过wget和curl下载未成功&#xff0c;使用手动…

Python 与 Java 在 Web 开发中的深度对比:从语言特性到生态选型

在 Web 开发领域&#xff0c;Python 和 Java 作为两大主流技术栈&#xff0c;始终是开发者技术选型时的核心考量。本文将从语言本质、框架生态、性能工程、工程实践等多个维度展开深度对比&#xff0c;结合具体技术场景解析两者的适用边界与融合方案&#xff0c;为开发者提供系…

【OpenGL学习】(一)创建窗口

文章目录 【OpenGL学习】&#xff08;一&#xff09;创建窗口 【OpenGL学习】&#xff08;一&#xff09;创建窗口 GLFW OpenGL 本身只是一套图形渲染 API&#xff0c;不提供窗口创建、上下文管理或输入处理的功能。 GLFW 是一个支持创建窗口、处理键盘鼠标输入和管理 OpenGL…

电脑闪屏可能的原因

1. 显示器 / 屏幕故障 屏幕排线接触不良&#xff1a;笔记本电脑屏幕排线&#xff08;屏线&#xff09;松动或磨损&#xff0c;导致信号传输不稳定&#xff0c;常见于频繁开合屏幕的设备。屏幕面板损坏&#xff1a;液晶屏内部灯管老化、背光模块故障或面板本身损坏&#xff0c;…

docker容器知识

一、docker与docker compose区别&#xff1a; 1、docker是创建和管理单个容器的工具&#xff0c;适合简单的应用或服务&#xff1b; 2、docker compose是管理多容器应用的工具&#xff0c;适合复杂的、多服务的应用程序&#xff1b; 3、docker与docker compose对比&#xff…

什么是Rootfs

Rootfs (Root Filesystem) 详解 buildroot工具构建了一个名为"rootfs.tar"的根文件系统压缩包。 什么是rootfs Rootfs&#xff08;Root Filesystem&#xff0c;根文件系统&#xff09;是操作系统启动后挂载的第一个文件系统&#xff0c;它包含系统正常运行所需的基…

关于NLP自然语言处理的简单总结

参考&#xff1a; 什么是自然语言处理&#xff1f;看这篇文章就够了&#xff01; - 知乎 (zhihu.com) 所谓自然语言理解&#xff0c;就是研究如何让机器能够理解我们人类的语言并给出一些回应。 自然语言处理&#xff08;Natural Language Processing&#xff0c;NLP&#xff0…

Linux下载国外软件镜像的加速方法(以下载Python-3.8.0.tgz为例)

0 前言 使用linux经常会通过国外服务器下载软件镜像&#xff0c;有些软件的下载速度奇慢&#xff0c;本文介绍一种加速国外软件镜像下载速度的方法&#xff0c;需要准备下载工具&#xff1a;迅雷。 1 以下载Python-3.8.0.tgz为例 找到Python官网的Python-3.8.0.tgz镜像下载地…

没有公网ip怎么端口映射外网访问?使用内网穿透可以解决

无公网IP时本地搭建的网络端口服务怎么映射外网远程访问&#xff1f;较为简单通用的方案就是使用nat123内网穿透&#xff0c;下面详细内网映射外网实现教程。​ 一、了解内网公网区别&#xff0c;及无公网IP外网访问方案 内网IP默认只能在同局域网内连接互通&#xff0c;而公…

Word2Vec详解

目录 Word2Vec 一、Word2Vec 模型架构 &#xff08;一&#xff09;Word2Vec 的核心理念 &#xff08;二&#xff09;Word2Vec 的两种架构 &#xff08;三&#xff09;负采样与层次 Softmax &#xff08;四&#xff09;Word2Vec 的优势与局限 二、Word2Vec 预训练及数据集…

ShardingSphere:查询报错:Actual table `数据源名称.表名` is not in table rule configuration

目录 简介异常信息排查原因解决 简介 1、使用ShardingSphere框架&#xff0c;版本为5.2.1 <dependency><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-jdbc-core</artifactId><version>5.2.1</version>…

MongoDB聚合查询:从入门到精通

文章目录 前言一、工具一般聚合查询分为四步 二、使用步骤1.MongoDB Compass2.Studio 3T 二、举个栗子总结 前言 Mongo 聚合查询 一般用mongo做数据库,涉及到关联查询情况不多,但是还有些情况要使用到,今天就讲下如何通过工具做关联查询,最终聚合结果,得到最终的查询结果集; …

codeup添加流水线docker自动化部署

在项目根目录下增加Dockerfile文件 # 使用基础镜像 FROM maven:3.8.4-openjdk-17-slim AS build # 设置工作目录 WORKDIR /app # 复制项目源代码 COPY . . # 构建项目 RUN mvn clean package -DskipTests # 验证JAR包是否生成 RUN ls -l target/your-project.jar # 使用合适的…

从 Word2Vec 到 BERT:AI 不止是词向量,更是语言理解

一、前言 在上篇文章中&#xff0c;我们介绍了Word2Vec以及它的作用&#xff0c;总的来说&#xff1a; Word2Vec是我们理解NLP的第一站 Word2Vec将词变成了“向量”—— 终于可以用机器理解词语的相似度 我们获得了例如“国王 - 男人 女人 ≈ 女王” 的类比能力 我们可以将…

镜像管理(2)Dockerfile总结

一、docker镜像构建方法 commoit :使用 docker commit 意味着所有对镜像的操作都是黑箱操作,生成的镜像也被称为黑 箱镜像,换句话说,就是除了制作镜像的人知道执行过什么命令、怎么生成的镜像,别人根 本无从得知。而且,即使是这个制作镜像的人,过一段时间后也无法记清具…

机器学习第十七讲:PCA → 把100维数据压缩成3D视图仍保持主要特征

机器学习第十七讲&#xff1a;PCA → 把100维数据压缩成3D视图仍保持主要特征 资料取自《零基础学机器学习》。 查看总目录&#xff1a;学习大纲 关于DeepSeek本地部署指南可以看下我之前写的文章&#xff1a;DeepSeek R1本地与线上满血版部署&#xff1a;超详细手把手指南 主…

【Linux庖丁解牛】——进程等待!

1. 进程退出场景 进程退出一般有三种场景&#xff1a; 。代码运行完毕&#xff0c;结果正确 。代码运行完毕&#xff0c;结果错误【比如&#xff0c;我们要对某个文件进行写入&#xff0c;但写入的文件路径出错&#xff0c;代码运行完毕&#xff0c;可是结果出错】 。代码异…

鸿蒙OSUniApp 制作简洁高效的标签云组件#三方框架 #Uniapp

UniApp 制作简洁高效的标签云组件 在移动端应用中&#xff0c;标签云&#xff08;Tag Cloud&#xff09;是一种常见的UI组件&#xff0c;它以视觉化的方式展示关键词或分类&#xff0c;帮助用户快速浏览和选择感兴趣的内容。本文将详细讲解如何在UniApp框架中实现一个简洁高效的…