MySQL索引明明建了,查询还是慢,排查发现踩了这些坑

背景

同事说他的SQL查询很慢,但他明明建了索引。

我过去一看:

SELECT * FROM orders WHERE user_id = 10086 AND status = 1;

表有500万数据,user_idstatus都有索引,但这条SQL执行要3秒。

用EXPLAIN一看:

EXPLAIN SELECT * FROM orders WHERE user_id = 10086 AND status = 1; +----+-------------+--------+------+---------------+------+---------+------+---------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+--------+------+---------------+------+---------+------+---------+-------------+ | 1 | SIMPLE | orders | ALL | idx_user_id | NULL | NULL | NULL | 5000000 | Using where | +----+-------------+--------+------+---------------+------+---------+------+---------+-------------+

type=ALL,全表扫描,索引根本没用上。

为什么?总结了索引失效的常见原因。

一、对索引列做运算或函数

错误示例

-- 对索引列使用函数 SELECT * FROM users WHERE YEAR(create_time) = 2024; -- 对索引列做运算 SELECT * FROM orders WHERE order_id + 1 = 10087;

原因

B+树索引存的是列的原始值,你用函数或运算处理后,MySQL没法直接用索引查找。

正确写法

-- 改成范围查询 SELECT * FROM users WHERE create_time >= '2024-01-01' AND create_time < '2025-01-01'; -- 把运算移到右边 SELECT * FROM orders WHERE order_id = 10087 - 1;

二、隐式类型转换

错误示例

-- phone是VARCHAR类型 SELECT * FROM users WHERE phone = 13800138000;

phone是字符串,但传入的是数字,MySQL会做隐式转换。

EXPLAIN结果

type: ALL key: NULL

索引失效了。

原因

MySQL的转换规则是:字符串转数字,而不是数字转字符串。

所以实际执行的是:

SELECT * FROM users WHERE CAST(phone AS SIGNED) = 13800138000;

等于对索引列做了函数处理,索引失效。

正确写法

SELECT * FROM users WHERE phone = '13800138000';

记住:类型要匹配,字符串就传字符串。

三、LIKE以%开头

错误示例

SELECT * FROM products WHERE name LIKE '%手机%';

原因

B+树索引是按顺序排列的,%手机%没法利用索引定位,只能全表扫描。

可以用索引的写法

-- 前缀匹配可以用索引 SELECT * FROM products WHERE name LIKE '手机%';

全文搜索怎么办

如果业务需要中间匹配:

  1. 全文索引:MySQL 5.7+支持中文全文索引
  2. Elasticsearch:专业的搜索引擎
  3. 搜索优化:用其他条件先过滤,再LIKE

四、OR条件只有部分有索引

错误示例

-- user_id有索引,remark没索引 SELECT * FROM orders WHERE user_id = 10086 OR remark = '测试';

EXPLAIN结果

type: ALL

全表扫描。

原因

OR的两个条件,只要有一个没索引,就没法用索引。

正确写法

-- 方案1:给remark也加索引 -- 方案2:改成UNION SELECT * FROM orders WHERE user_id = 10086 UNION SELECT * FROM orders WHERE remark = '测试';

五、联合索引没遵循最左前缀

假设有联合索引

CREATE INDEX idx_abc ON orders(a, b, c);

能用上索引的查询

WHERE a = 1 WHERE a = 1 AND b = 2 WHERE a = 1 AND b = 2 AND c = 3 WHERE a = 1 AND c = 3 -- 只能用到a

用不上索引的查询

WHERE b = 2 -- 没有a,最左前缀断了 WHERE b = 2 AND c = 3 -- 没有a WHERE c = 3 -- 没有a

原理

联合索引的B+树是按(a, b, c)顺序排列的,先按a排序,a相同的按b排序,b相同的按c排序。

如果查询不包含a,就没法利用这个排序结构。

六、范围查询后的列失效

联合索引

CREATE INDEX idx_abc ON orders(a, b, c);

查询

SELECT * FROM orders WHERE a = 1 AND b > 10 AND c = 3;

实际用到的索引

只用到了abc没用上。

原因

范围查询(>、<、BETWEEN、LIKE)会导致后面的列无法使用索引。

因为在b > 10的范围内,c的值不是有序的。

优化建议

把等值查询的列放前面,范围查询的列放后面:

CREATE INDEX idx_acb ON orders(a, c, b);

七、NOT IN和NOT EXISTS

示例

SELECT * FROM users WHERE id NOT IN (SELECT user_id FROM blacklist);

情况

  • IN通常可以用索引
  • NOT IN某些情况会导致全表扫描

优化

-- 用LEFT JOIN替代 SELECT u.* FROM users u LEFT JOIN blacklist b ON u.id = b.user_id WHERE b.user_id IS NULL;

八、使用!=或<>

示例

SELECT * FROM orders WHERE status != 1;

情况

不等于查询有时候会导致索引失效,取决于数据分布。

如果status != 1的数据占大多数,MySQL可能认为全表扫描更快。

建议

用EXPLAIN看实际执行计划,如果数据分布合适,可以改成:

SELECT * FROM orders WHERE status IN (0, 2, 3, 4);

九、IS NULL的情况

老版本MySQL

IS NULL可能导致索引失效。

MySQL 5.7+

IS NULL可以使用索引:

SELECT * FROM users WHERE phone IS NULL; -- 可以用索引

建议

  • 尽量不要用NULL,用默认值代替
  • 如果必须用NULL,确保MySQL版本较新

十、ORDER BY没用上索引

联合索引

CREATE INDEX idx_abc ON orders(a, b, c);

能用索引排序的

ORDER BY a ORDER BY a, b ORDER BY a, b, c ORDER BY a DESC, b DESC, c DESC -- 方向一致

不能用索引排序的

ORDER BY b -- 没有a ORDER BY a ASC, b DESC -- 方向不一致 ORDER BY a, c -- 跳过了b

排查索引问题的流程

  1. EXPLAIN看执行计划
  • type:ALL是全表扫描,ref/range/const是用了索引
  • key:实际使用的索引
  • rows:预估扫描行数
  1. 看possible_keys和key
  • possible_keys有值但key是NULL:索引存在但没用上
  1. 开启optimizer_trace
    SET optimizer_trace = 'enabled=on'; SELECT * FROM orders WHERE ...; SELECT * FROM information_schema.optimizer_trace\G
    可以看到MySQL为什么选择了某个执行计划。

总结

索引失效的常见原因:

原因示例解决方案
对索引列做函数WHERE YEAR(date)=2024改成范围查询
隐式类型转换WHERE phone=138xxx(数字)类型匹配
LIKE %开头WHERE name LIKE '%xxx'改前缀或用ES
OR部分无索引WHERE a=1 OR b=2都加索引或UNION
最左前缀联合索引(a,b,c)查WHERE b=1调整索引或查询
范围查询后的列WHERE a>1 AND b=2调整索引顺序

记住:写完SQL先EXPLAIN,养成习惯。

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

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

相关文章

改进人工蜂群算法优化主动悬架控制策略【附代码】

✅ 博主简介&#xff1a;擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导&#xff0c;毕业论文、期刊论文经验交流。✅成品或者定制&#xff0c;扫描文章底部微信二维码。(1) 改进人工蜂群算法优化的PID控制器设计主动悬架系统的性能很大程度上取决于控制器…

教育特供版:如何在校园网环境下快速部署Z-Image-Turbo

教育特供版&#xff1a;如何在校园网环境下快速部署Z-Image-Turbo 作为一名计算机实验室管理员&#xff0c;你是否遇到过这样的困境&#xff1a;想要为学生搭建AI图像生成学习环境&#xff0c;但校园网的网络限制、软件安装权限等问题让部署变得异常困难&#xff1f;本文将介绍…

毕设成品 基于单片机的姿态检测与可视化系统(源码+硬件+论文)

文章目录 1 前言2 设计方案2.1 MPU60502.2 工作原理2.3 单片机与MPU6050通信2.4 mpu6050 数据格式2.5 倾角计算方法 3 核心软件设计4 实现效果5 最后 1 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#x…

基于Django的在线课程学习平台 计算机毕业设计选题 计算机毕设项目 前后端分离【源码-文档报告-代码讲解】

&#x1f34a;作者&#xff1a;计算机毕设匠心工作室 &#x1f34a;简介&#xff1a;毕业后就一直专业从事计算机软件程序开发&#xff0c;至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长&#xff1a;按照需求定制化开发项目…

零成本启动:用免费云端GPU快速运行阿里通义Z-Image-Turbo WebUI

零成本启动&#xff1a;用免费云端GPU快速运行阿里通义Z-Image-Turbo WebUI 作为一名学生党&#xff0c;想要完成AI图像生成相关的课程项目&#xff0c;却苦于个人电脑性能不足&#xff0c;又难以承担高昂的云计算费用&#xff1f;别担心&#xff0c;本文将带你零成本快速上手阿…

非光滑复合优化加速邻近梯度算法【附代码】

✅ 博主简介&#xff1a;擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导&#xff0c;毕业论文、期刊论文经验交流。✅成品或者定制&#xff0c;扫描文章底部微信二维码。(1) 自适应非单调步长策略与惯性加速机制设计邻近梯度算法在求解非光滑复合优化问题时…

教学实践:如何在计算机视觉课程中快速集成Z-Image-Turbo

教学实践&#xff1a;如何在计算机视觉课程中快速集成Z-Image-Turbo 作为一名计算机视觉课程的讲师&#xff0c;我最近在准备生成式AI的教学内容时&#xff0c;发现学生常因本地环境配置差异导致课堂进度延误。经过多次测试&#xff0c;Z-Image-Turbo 凭借其亚秒级图像生成能力…

org.mockito : mockito-core 中文文档(中英对照·API·接口·操作手册·全版本)以4.11.0为例,含Maven依赖、jar包、源码

文章目录完整文档下载地址&#xff08;类、方法、参数说明&#xff09;mockito-core-4.11.0.jar中文-英文对照文档.zip 中包含以下内容使用方法组件信息简介Maven依赖Gradle依赖寒水馨 Java 组件中文文档系列说明版权声明与来源信息本组件包含的 Java package&#xff08;包&am…

进化多目标优化算法设计与实现【附代码】

✅ 博主简介&#xff1a;擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导&#xff0c;毕业论文、期刊论文经验交流。✅成品或者定制&#xff0c;扫描文章底部微信二维码。(1) 基于角度向量的支配准则设计多目标优化问题的求解核心在于如何有效引导种群向Par…

终极对比:本地部署vs云端Z-Image-Turbo镜像,哪种方式更适合你的项目?

终极对比&#xff1a;本地部署vs云端Z-Image-Turbo镜像&#xff0c;哪种方式更适合你的项目&#xff1f; 作为技术负责人&#xff0c;当你计划为团队引入Z-Image-Turbo这类AI图像生成能力时&#xff0c;第一个关键决策就是&#xff1a;选择本地部署还是云端服务&#xff1f;本文…

毕业设计救星:基于预装镜像的Z-Image-Turbo二次开发全指南

毕业设计救星&#xff1a;基于预装镜像的Z-Image-Turbo二次开发全指南 作为一名数字媒体专业的学生&#xff0c;毕业设计答辩时如果能展示AI图像生成能力&#xff0c;无疑会为作品增色不少。但现实往往很骨感——实验室电脑性能不足&#xff0c;个人笔记本又难以搞定复杂的AI环…

Z-Image-Turbo多GPU部署指南:如何实现高并发图像生成

Z-Image-Turbo多GPU部署指南&#xff1a;如何实现高并发图像生成 在当今SaaS平台快速发展的背景下&#xff0c;高并发AI图像生成需求日益增长。Z-Image-Turbo作为阿里开源的6B参数图像生成模型&#xff0c;通过创新的8步蒸馏技术&#xff0c;能在保持照片级质量的同时实现亚秒级…

快速迭代:阿里通义Z-Image-Turbo开发测试环境搭建

快速迭代&#xff1a;阿里通义Z-Image-Turbo开发测试环境搭建 为什么需要快速迭代的开发测试环境&#xff1f; 作为AI研发团队的成员&#xff0c;我深刻体会到频繁测试模型不同版本时的痛点。每次切换模型版本时&#xff0c;环境配置、依赖安装、CUDA版本冲突等问题总会消耗大量…

两通道正交镜像滤波器组系数稀疏优化【附代码】

✅ 博主简介&#xff1a;擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导&#xff0c;毕业论文、期刊论文经验交流。✅成品或者定制&#xff0c;扫描文章底部微信二维码。(1) 基于信赖域迭代梯度搜索的初优化方法两通道正交镜像滤波器组的设计核心在于确定原…

ue 编译

"D:\Program Files\Epic Games\UE_5.6\Engine\Build\BatchFiles\Build.bat" ^ MetahumanHeiXiEditor Win64 Development ^ -Project"D:\soft\ue\MetahumanHeiXi_56_dong\MetahumanHeiXi_56_dong\MetahumanHeiXi.uproject"

毕业设计救星:基于预置镜像的Z-Image-Turbo二次开发实战

毕业设计救星&#xff1a;基于预置镜像的Z-Image-Turbo二次开发实战 作为一名数字媒体专业的学生&#xff0c;你是否正在为毕业设计中的AI图像生成功能发愁&#xff1f;实验室电脑性能不足&#xff0c;本地搭建环境又总是卡在依赖安装和配置环节&#xff1f;今天我要分享的Z-Im…

AI绘画工作坊必备:15分钟搭建Z-Image-Turbo教学环境

AI绘画工作坊必备&#xff1a;15分钟搭建Z-Image-Turbo教学环境 作为一名经常开设AI绘画课程的技术讲师&#xff0c;我深知教学过程中最头疼的问题就是学员的电脑配置参差不齐。有些同学用着高性能显卡轻松跑图&#xff0c;而另一些同学则卡在依赖安装或显存不足的环节。最近我…

教学实践:如何在计算机课堂快速部署Z-Image-Turbo实验环境

教学实践&#xff1a;如何在计算机课堂快速部署Z-Image-Turbo实验环境 作为一名高校教师&#xff0c;你是否遇到过这样的困境&#xff1a;想要将前沿的AI绘画技术引入计算机课程教学&#xff0c;但实验室电脑配置参差不齐&#xff0c;导致学生无法获得一致的实验体验&#xff1…

程序员的终身学习:如何应对技术迭代的加速?

程序员的终身学习&#xff1a;如何应对技术迭代的加速&#xff1f;关键词&#xff1a;程序员、终身学习、技术迭代、学习策略、职业发展摘要&#xff1a;在当今科技飞速发展的时代&#xff0c;技术迭代的速度不断加快&#xff0c;这对程序员提出了极高的要求。程序员需要进行终…

同城配送一致性车辆路径优化模型【附代码】

✅ 博主简介&#xff1a;擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导&#xff0c;毕业论文、期刊论文经验交流。✅成品或者定制&#xff0c;扫描文章底部微信二维码。(1) 多场景协同优化的一致性概念框架与时空网络建模同城配送作为物流服务的末端环节&…