当前位置: 首页 > article >正文

MySQL 索引失效的 8 种场景,90% 开发者都踩过坑

MySQL 索引失效的 8 种场景90% 开发者都踩过坑导读你是否遇到过这样的尴尬明明给字段加了索引EXPLAIN一看却全是ALL全表扫描查询慢如蜗牛CPU 飙升到 100%在 MySQL 性能优化中“索引失效”是最隐蔽也最致命的陷阱。本文深入剖析导致索引失效的 8 大经典场景结合真实代码案例和底层原理助你彻底避开这些深坑让查询飞起来一、为什么索引会“凭空消失”MySQL 的索引尤其是 B 树索引是有序的数据结构。优化器Optimizer决定是否使用索引的核心逻辑很简单如果通过索引查找的成本 全表扫描的成本则走索引否则直接全表扫描。但在很多情况下由于 SQL 写法不当或数据类型隐式转换优化器被迫放弃索引。以下是 8 种最高频的“翻车”现场。场景 1最左前缀法则被打破复合索引篇❌ 错误写法 假设有一个复合索引idx_name_age_city(name, age, city)。-- 情况 A跳过中间列 SELECT * FROM user WHERE name 张三 AND city 北京; -- 结果name 走索引age 和 city 不走索引因为 age 断了 -- 情况 B直接从第二列开始查 SELECT * FROM user WHERE age 25 AND city 北京; -- 结果索引完全失效全表扫描✅ 正确写法 必须严格遵循最左前缀原则从索引的最左边列开始匹配不能跳过中间的列。-- 只有这种写法能完美利用索引 SELECT * FROM user WHERE name 张三 AND age 25 AND city 北京; -- 或者只查前两列 SELECT * FROM user WHERE name 张三 AND age 25;原理B 树是先按name排序name相同再按age排序。如果没指定nameage在全局是无序的索引无法定位。场景 2在索引列上做计算或函数操作❌ 错误写法-- 对索引列进行函数运算 SELECT * FROM order WHERE DATE(create_time) 2026-03-14; -- 对索引列进行计算 SELECT * FROM product WHERE price * 0.9 100;✅ 正确写法 将计算移到等号右边保持索引列的“纯净”。-- 改造为范围查询 SELECT * FROM order WHERE create_time 2026-03-14 00:00:00 AND create_time 2026-03-15 00:00:00; -- 移项处理 SELECT * FROM product WHERE price 100 / 0.9;原理索引存储的是原始值。如果对列做了函数处理MySQL 必须取出每一行数据计算后才能比较这等同于全表扫描。场景 3隐式类型转换字符串不加引号这是新手最容易踩的坑也是生产环境最常见的“幽灵”问题。❌ 错误写法 假设phone字段是VARCHAR类型。-- 数字没有加引号MySQL 会自动把 phone 转为数字进行比较 SELECT * FROM user WHERE phone 13800138000;✅ 正确写法-- 加上引号保持类型一致 SELECT * FROM user WHERE phone 13800138000;原理当字符串字段与数字比较时MySQL 会将字符串字段隐式转换为数字类似CAST(phone AS SIGNED)。一旦对列进行了类型转换函数操作索引立即失效检查方法EXPLAIN结果中Extra列出现Using where且type为ALL或index而非ref。场景 4模糊查询%在前缀❌ 错误写法-- 通配符在最前面 SELECT * FROM user WHERE name LIKE %张%; SELECT * FROM user WHERE name LIKE %三;✅ 正确写法-- 通配符只在后面可以走索引 SELECT * FROM user WHERE name LIKE 张%;原理B 树是从左向右排序的。张%可以利用有序性快速定位到“张”开头的所有记录而%张意味着“张”可能出现在任何位置破坏了有序性只能全表扫描。进阶方案如果必须前缀模糊搜索考虑使用Elasticsearch或倒排索引。场景 5OR 连接条件中包含非索引列❌ 错误写法-- name 有索引但 email 没有索引 SELECT * FROM user WHERE name 张三 OR email testexample.com;✅ 正确写法 确保OR两边的字段都有索引或者改写为UNION ALL。-- 方案 A给 email 也加上索引 ALTER TABLE user ADD INDEX idx_email (email); -- 方案 B手动拆分查询推荐更可控 SELECT * FROM user WHERE name 张三 UNION ALL SELECT * FROM user WHERE email testexample.com;原理只要OR连接的条件中有一个字段没索引优化器为了保证数据完整性往往会放弃所有索引直接全表扫描。场景 6NOT IN / ! / 操作❌ 错误写法SELECT * FROM user WHERE status ! 1; SELECT * FROM user WHERE id NOT IN (1, 2, 3);✅ 优化思路 尽量避免使用否定操作符。如果业务允许改为正向查询或使用IS NULL配合特定逻辑。-- 如果状态只有 1(正常) 和 0(删除)查删除的可以用 SELECT * FROM user WHERE status 0; -- 对于 NOT IN如果数据量小没关系数据量大时考虑用 LEFT JOIN IS NULL 替代 SELECT u.* FROM user u LEFT JOIN black_list b ON u.id b.user_id WHERE b.user_id IS NULL;原理不等于或不包含通常意味着要扫描大部分数据优化器认为全表扫描效率更高。但在某些覆盖索引场景下MySQL 8.0 可能会尝试使用索引但不稳定。场景 7IS NULL 与 IS NOT NULL 的误区很多人认为IS NULL一定不走索引其实不然。情况 A如果字段定义为NOT NULL则IS NULL肯定查不到数据优化器直接优化掉。情况 B如果字段允许NULL且NULL值占比很高例如超过 20%优化器可能放弃索引。情况 C如果是覆盖索引Covering Index即使IS NOT NULL也可能走索引。✅ 最佳实践 尽量将字段定义为NOT NULL并设置默认值如 0 或空字符串。这样不仅能避免索引失效的歧义还能节省存储空间。-- 推荐定义 CREATE TABLE user ( id INT PRIMARY KEY, age INT NOT NULL DEFAULT 0, ... );场景 8字符集不一致导致隐式转换这是一个跨表关联JOIN时的高发场景。❌ 错误写法 表 A 的user_id是utf8字符集表 B 的user_id是utf8mb4字符集。SELECT * FROM order o JOIN user u ON o.user_id u.user_id;✅ 正确写法 确保关联字段的字符集和排序规则Collation完全一致。-- 修改表字符集 ALTER TABLE order MODIFY user_id VARCHAR(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;原理字符集不同会导致 MySQL 在关联时进行隐式的字符集转换函数操作从而导致驱动表的索引失效。️ 实战工具箱如何快速发现索引失效不要猜用工具说话1. EXPLAIN 命令这是最基本的诊断工具。重点关注以下字段typesystemconsteq_refrefrangeindexALL。如果出现ALL或index警惕key实际使用的索引。如果是NULL说明没用到索引。rows预计扫描行数。越大越慢。ExtraUsing filesort需要额外排序性能差。Using temporary使用了临时表性能差。Using index condition正常走索引。2. Slow Query Log开启慢查询日志捕获执行时间超过阈值如 1s的 SQL。[mysqld] slow_query_log 1 long_query_time 1 log_queries_not_using_indexes 1 # 重点记录没用索引的查询3. pt-query-digestPercona toolkit 的神器分析慢日志聚合出最耗资源的 SQL 模板。 总结避坑口诀为了方便记忆送大家一首《索引避坑歌》最左前缀要记牢中间断开全扫飘。 列上莫把函数套计算统统右边抛。 字符串要加引号隐式转换是毒药。 百分号别放头跑OR 两边索引保。 字符集需对齐好NOT IN 尽量少。 遇事不决 Explain性能优化没烦恼最后的话 索引不是万能药乱加索引反而拖慢写入速度。真正的优化在于理解业务场景写出符合 B 树特性的 SQL。下次写 SQL 时先问自己一句“这条语句会让我的索引失效吗”

相关文章:

MySQL 索引失效的 8 种场景,90% 开发者都踩过坑

MySQL 索引失效的 8 种场景,90% 开发者都踩过坑导读:你是否遇到过这样的尴尬:明明给字段加了索引,EXPLAIN 一看却全是 ALL(全表扫描)?查询慢如蜗牛,CPU 飙升到 100%?在 M…...

快速配置Anaconda清华镜像源安装PyTorch(CPU版)全流程解析

1. 为什么你需要换源?一个真实的故事 我刚开始学深度学习那会儿,装PyTorch这事儿差点把我劝退。那时候啥也不懂,就跟着官网教程,在Anaconda Prompt里输入了那个经典的 conda install pytorch torchvision torchaudio cpuonly -c p…...

架构师视角:达梦数据库CLOB字段写入性能深度调优实战

1. 从一次线上故障说起:CLOB写入为何成了性能瓶颈? 去年我们团队接手了一个内容发布平台的性能优化项目,这个平台每天要处理几十万篇自媒体文章的入库。刚接手时,系统一到晚高峰就频繁告警,数据库响应时间飙升&#xf…...

操作系统原理:优化Baichuan-M2-32B医疗AI系统资源调度

操作系统原理:优化Baichuan-M2-32B医疗AI系统资源调度 1. 医疗AI系统面临的现实调度困境 在医院信息科的实际工作中,我们经常遇到这样的场景:一台配置了RTX 4090显卡的服务器,部署了Baichuan-M2-32B-GPTQ-Int4医疗大模型后&…...

Carsim与Simulink联合仿真:数据后处理实战与效率提升

1. 联合仿真数据后处理:为什么它如此重要? 如果你和我一样,是一名整天和车辆动力学、控制策略打交道的工程师,那你肯定对Carsim和Simulink这对“黄金搭档”不陌生。我们花大量时间搭建模型、调试参数、跑仿真,最终的目…...

使用Xshell管理Qwen-Image-Edit-F2P远程服务器

使用Xshell管理Qwen-Image-Edit-F2P远程服务器 1. 引言 如果你正在运行Qwen-Image-Edit-F2P这样的人脸生成图像模型,很可能需要管理远程服务器。无论是部署在云端的GPU实例,还是本地数据中心的计算节点,稳定高效的远程连接都是确保模型持续…...

解锁AMD Ryzen潜能:SMUDebugTool硬件调试完全指南

解锁AMD Ryzen潜能:SMUDebugTool硬件调试完全指南 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://gitcod…...

2.46 基于立创梁山派GD32F470的INA226高精度电流电压功率监测模块移植与驱动开发

基于立创梁山派GD32F470的INA226高精度电流电压功率监测模块移植与驱动开发 最近在做一个电池供电的小项目,需要精确监测系统的功耗,找来找去发现了TI的INA226这个芯片。它精度高、使用简单,正好手头有块立创的梁山派开发板(GD32F…...

Qwen2.5-72B-Instruct-GPTQ效果展示:跨语言代码生成与注释翻译

Qwen2.5-72B-Instruct-GPTQ效果展示:跨语言代码生成与注释翻译 最近,一个名为Qwen2.5-72B-Instruct-GPTQ-Int4的模型镜像在开发者社区里引起了不小的讨论。这个模型基于通义千问最新的Qwen2.5系列,经过GPTQ量化到4位精度,并通过v…...

DRAM-Less SSD真的更差吗?HMB技术详解与选购避坑指南

DRAM-Less SSD真的更差吗?HMB技术详解与选购避坑指南 最近帮朋友装机,他盯着购物车里两款价格相差近百元的固态硬盘犯了难:一款是经典的带独立DRAM缓存的型号,另一款则是标注了“DRAM-Less”但支持“HMB”技术的产品。他问我&…...

Spire.Doc 1.6版本License实战指南:从开发到部署的完整流程

1. 为什么你需要关注Spire.Doc 1.6版本的License? 如果你正在用C#或者.NET做Word文档处理,那你大概率听说过或者用过Spire.Doc这个库。它确实是个好东西,能帮你省去大量操作Word文档的底层代码。但很多朋友在项目从开发测试走向正式部署时&am…...

深入解析CAN数据帧:从结构到应用场景

1. CAN数据帧到底是什么?从“汽车神经”说起 如果你拆开过一辆现代汽车,或者看过工业产线的控制柜,里面除了各种机械部件和电线,总少不了几块黑色的盒子,它们之间通过一些看似普通的双绞线连接。这些不起眼的线缆&…...

Oracle19c安装实战:从软件部署到监听配置的完整指南

1. 环境准备:别急着点安装,先把地基打牢 每次看到有朋友一上来就下载Oracle19c的安装包,然后直接双击runInstaller,我心里都捏一把汗。这就像盖房子不打地基,装修完了才发现墙是歪的,到时候再想调整&#x…...

【C++进阶】std::vector性能优化与实战技巧

1. 理解std::vector的性能瓶颈:为什么你的代码会变慢? 很多C开发者,包括我自己,刚开始用std::vector的时候都觉得它就是个“动态数组”,用起来挺顺手。但真正在项目里处理大量数据时,才发现事情没那么简单。…...

MBT:基于多频带迁移的语义分割域自适应新范式

1. 从“水土不服”到“入乡随俗”:为什么语义分割需要域自适应? 大家好,我是老张,在AI和计算机视觉领域摸爬滚打了十几年,做过不少自动驾驶相关的项目。今天想和大家聊聊一个在实际落地时,工程师们几乎百分…...

OpenFeign负载均衡策略深度定制:场景化方案与性能调优

1. 为什么默认的轮询策略不够用?从真实业务场景说起 大家好,我是老张,在微服务这行摸爬滚打十来年了。今天咱们不聊那些高大上的理论,就聊聊一个实实在在的问题:用Spring Cloud做微服务,OpenFeign调服务默认…...

嵌入式硬件实战:嘉立创PCB设计从入门到精通

1. 从零开始:为什么嵌入式开发者必须掌握PCB设计? 很多刚入行的嵌入式软件工程师,或者是从单片机编程转过来的朋友,常常会有一种误解:硬件设计是硬件工程师的事,我只要会写代码、调驱动就行了。我以前也是这…...

OSD IP核的常见报错分析与高效解决方法

1. 从一次深夜报错说起:OSD IP核的“入门杀” 那天晚上,我盯着Vivado里那一串鲜红的报错信息,感觉血压都上来了。项目卡在最后一步,就因为这个OSD(On-Screen Display)IP核死活生成不了。报错信息长得让人头…...

如何通过智能语音识别实现Windows平台的效率革命

如何通过智能语音识别实现Windows平台的效率革命 【免费下载链接】TMSpeech 腾讯会议摸鱼工具 项目地址: https://gitcode.com/gh_mirrors/tm/TMSpeech 在数字化办公日益普及的今天,高效处理语音信息已成为提升工作效率的关键环节。TMSpeech作为一款专为Wind…...

[技术解析] 通用可迁移对抗性后缀:如何攻破对齐大语言模型的安全防线

1. 从“越狱”到“通用攻击”:大模型安全防线的新挑战 不知道你有没有试过,跟ChatGPT或者Claude聊天时,突然问它一个敏感问题,比如“怎么制造危险物品”或者“如何攻击某个网站”。绝大多数时候,这些被精心“对齐”过的…...

nRF5340双核开发实战:从环境搭建到蓝牙例程调试

1. 从nRF52到nRF5340:开发环境的“世界观”转变 如果你和我一样,是从经典的nRF52系列,用着Keil MDK,写着熟悉的C代码一路走过来的,那么第一次接触nRF5340和它的nRF Connect SDK(NCS)时&#xff…...

Ubuntu 22.04 上,从零构建 Isaac Sim 5.1.0 与 Isaac Lab 2.3.0 的 Conda 开发环境

1. 为什么需要一个独立的Conda环境? 如果你刚刚接触机器人仿真或者强化学习,可能会觉得直接在自己的电脑上安装各种软件包不就行了?我以前也是这么想的,直到我的系统环境被各种不同版本的Python和库搞得一团糟,一个项目…...

Synopsys DC 综合实战:从RTL到门级网表的优化之旅

1. 从RTL到GDSII:为什么综合是关键一步? 如果你刚接触数字芯片设计,可能会觉得从写Verilog代码到最终芯片生产,中间隔着一座大山。这座大山里,有一个环节至关重要,它决定了你写的“想法”(RTL代…...

点云数据处理实战:PCL与CloudCompare双引擎驱动下的格式互转方案

1. 为什么你需要一个双引擎的点云格式转换方案? 刚接触点云处理的朋友,可能觉得格式转换不就是“另存为”吗?用个软件打开再保存不就行了?我刚开始也是这么想的,直到在实际项目中踩了几个大坑。比如,一个三…...

LFM2.5-1.2B-Thinking快速部署教程:Ollama开箱即用,无需conda环境

LFM2.5-1.2B-Thinking快速部署教程:Ollama开箱即用,无需conda环境 你是不是曾经被复杂的AI模型部署搞得头疼?需要安装conda、配置环境、解决各种依赖问题,光是准备工作就要花上大半天时间。现在有个好消息:LFM2.5-1.2…...

从仿真到实战:在快马平台构建平衡小车pid控制项目,模拟真实控制场景

最近在琢磨PID控制算法,想找个能直观看到效果、还能动手调参的练习项目。理论看了不少,但总觉得隔着一层,直到我尝试用仿真来模拟一个经典场景:两轮自平衡小车。这玩意儿在无人机、机器人里太常见了,核心就是靠PID让摇…...

快马平台一键生成jmeter性能测试脚本,快速原型验证接口并发能力

最近在做一个新项目的性能评估,需要快速验证几个核心接口在高并发下的表现。以前用JMeter写测试脚本,总得手动配置线程组、采样器、监听器,虽然功能强大,但准备阶段还是挺花时间的。这次我尝试了一个新思路,用InsCode(…...

基于STM32G0B1的立创开源隔离式RS485-CAN通讯监测器设计与实现

基于STM32G0B1的立创开源隔离式RS485-CAN通讯监测器设计与实现 最近在做一个工业现场的数据采集项目,需要同时监听RS485和CAN总线上的数据。市面上的成品要么功能单一,要么价格不菲。于是,我决定自己动手设计一个。这个项目最终做成了一块集成…...

抖音直播下载工具:从内容流失到价值留存的全流程解决方案

抖音直播下载工具:从内容流失到价值留存的全流程解决方案 【免费下载链接】douyin-downloader 项目地址: https://gitcode.com/GitHub_Trending/do/douyin-downloader 问题发现:直播内容管理的五大核心痛点 在数字内容爆炸的时代,抖…...

cv_resnet50_face-reconstruction模型多视角重建技术详解

cv_resnet50_face-reconstruction模型多视角重建技术详解 1. 引言 你有没有想过,用几张不同角度的自拍照就能生成一个逼真的3D人脸模型?这听起来像是科幻电影里的场景,但现在已经成为了现实。今天我们要聊的cv_resnet50_face-reconstructio…...