MySQL索引,这回真讲明白了
数据库慢查询是每个后端都会遇到的问题而90%的慢查询问题都可以通过合理设计索引来解决。这篇文章不聊深奥的底层原理从实际使用的角度讲清楚索引。索引到底是什么你可以把索引理解为一本书的目录。没有索引你要从头翻到尾找内容有了索引直接查目录跳到对应页码。MySQL的InnoDB引擎用的是B树索引。叶子节点存储数据非叶子节点只存索引值和指针。B树的好处是树的高度低3层能存几千万条数据范围查询效率高叶子节点有双向指针链。sql-- 没有索引时这条SQL会全表扫描 SELECT * FROM users WHERE email zhangsanexample.com; -- 创建索引后直接走B树查找速度提升几十倍 CREATE INDEX idx_email ON users(email);主键索引与二级索引InnoDB中数据是按照主键组织的所以主键索引的叶子节点直接存储完整的数据行这叫聚簇索引。而普通索引二级索引的叶子节点存储的是主键的值。通过二级索引查数据需要先找到主键再回主键索引取完整数据这个过程叫回表。sql-- 假设users表有主键id还有二级索引idx_name CREATE INDEX idx_name ON users(name); -- 这条SQL只需要查name和id索引里就有不用回表 SELECT id, name FROM users WHERE name 张三; -- 这条SQL要查email索引里没有需要回表取完整数据 SELECT id, name, email FROM users WHERE name 张三;最左前缀原则这是使用联合索引时最重要的原则也是面试高频考点。sql-- 创建联合索引 (name, age, city) CREATE INDEX idx_name_age_city ON users(name, age, city); -- ✅ 能用到索引 SELECT * FROM users WHERE name 张三; SELECT * FROM users WHERE name 张三 AND age 25; SELECT * FROM users WHERE name 张三 AND age 25 AND city 北京; -- ✅ 注意where条件的顺序不影响优化器会自动调整 SELECT * FROM users WHERE age 25 AND name 张三; -- 也能用到 -- ❌ 用不到索引跳过了name SELECT * FROM users WHERE age 25; SELECT * FROM users WHERE city 北京; SELECT * FROM users WHERE age 25 AND city 北京;联合索引从左往右匹配跳过了前面的字段就用不了索引。所以建联合索引时区分度高的字段放左边。sql-- 假设name区分度比age高这样建更合理 CREATE INDEX idx_name_age ON users(name, age); -- 而不是 idx_age_name覆盖索引与回表前面提到了回表。如果查询的字段都在索引里就不用回表了这叫覆盖索引性能会好很多。sql-- 索引是 (name, age) -- ✅ 覆盖索引查询字段都在索引中 SELECT name, age FROM users WHERE name 张三; -- ❌ 需要回表查询了不在索引中的字段 SELECT * FROM users WHERE name 张三;所以写SQL的时候尽量只查需要的字段少用SELECT *既减少网络传输也可能利用覆盖索引避免回表。索引失效的常见场景实际开发中建了索引但SQL没用上是经常发生的事情。以下场景索引会失效1. 在索引列上用函数sql-- ❌ 索引失效 SELECT * FROM orders WHERE DATE(create_time) 2024-01-01; -- ✅ 改成范围查询 SELECT * FROM orders WHERE create_time 2024-01-01 AND create_time 2024-01-02;2. 隐式类型转换sql-- 假设phone是varchar类型 -- ❌ 索引失效传了数字发生类型转换 SELECT * FROM users WHERE phone 13800138000; -- ✅ 传字符串 SELECT * FROM users WHERE phone 13800138000;3. LIKE以%开头sql-- ❌ 索引失效 SELECT * FROM users WHERE name LIKE %三; -- ✅ 可以用到索引 SELECT * FROM users WHERE name LIKE 张%;4. OR条件中有非索引列sql-- 假设name有索引age没有索引 -- ❌ 索引失效OR两边都要能用索引才行 SELECT * FROM users WHERE name 张三 OR age 25; -- ✅ 把age也建上索引或者用UNION SELECT * FROM users WHERE name 张三 UNION SELECT * FROM users WHERE age 25;5. 索引列参与计算sql-- ❌ 索引失效 SELECT * FROM products WHERE price * 0.8 100; -- ✅ 把计算移到右边 SELECT * FROM products WHERE price 100 / 0.8;6. 使用不等于! 或 或 IS NULLsql-- 不等于和IS NULL通常不走索引 SELECT * FROM users WHERE status ! 1;用EXPLAIN分析SQL遇到慢查询第一件事就是用EXPLAIN看执行计划。sqlEXPLAIN SELECT * FROM users WHERE name 张三;输出结果重点看这几列列名含义关注点type访问类型至少要到range或refALL就是全表扫描possible_keys可能用的索引看有没有预期中的索引key实际用的索引如果是NULL说明索引没用到rows扫描的行数这个值越大性能越差Extra额外信息出现Using filesort或Using temporary要警惕type的优劣排序从好到差systemconsteq_refrefrangeindexALL目标至少达到range级别。实战建索引的建议1. 不要建太多索引每个索引都占用磁盘空间且拖慢INSERT、UPDATE、DELETE的速度。一个表一般建议不超过5个索引。2. 区分度不高的字段不建索引比如性别男/女走索引还不如全表扫描快。sql-- 区分度 COUNT(DISTINCT column) / COUNT(*) -- 区分度低于10%的字段建索引效果不好 SELECT COUNT(DISTINCT gender) / COUNT(*) FROM users; -- 约 0.5%3. 长字符串用前缀索引sql-- 只对前20个字符建索引节省空间 CREATE INDEX idx_content ON articles(content(20));4. 频繁查询的字段优先建索引WHERE条件中频繁出现的字段ORDER BY排序的字段GROUP BY分组的字段JOIN连接的条件字段5. 不要用UUID作为主键UUID是随机字符串插入时会导致B树频繁分裂性能很差。建议用自增ID或者有序的雪花ID。总结索引的核心理念就一句话用空间换时间让查询少扫描数据。用好索引的要点搞懂最左前缀原则合理设计联合索引避免索引失效的写法函数、类型转换、前置%用EXPLAIN验证执行计划覆盖索引优于回表索引不是越多越好要精准索引是数据库性能优化的第一板斧掌握好它能解决绝大部分慢查询问题。

相关新闻

URA2415LD-15WR3 适配优选 VB15-24D15LD,15W 工业 DC-DC 模块电源参数规格全拆解

URA2415LD-15WR3 适配优选 VB15-24D15LD,15W 工业 DC-DC 模块电源参数规格全拆解

在工业电子整机研发阶段,硬件工程师针对模拟采集、信号变送、伺服控制等电路开展电源方案设计时,15W 等级 24V 输入双路 15V 输出 DC-DC 隔离电源属于高频选用器件。在多品牌、多系列直流电源模块横向筛选过程中,钡特电源 VB15-24D15LD 与 UR…

2026/10/14 8:13:33 阅读更多 →
直播间商品自动上下架系统的通用设计方案

直播间商品自动上下架系统的通用设计方案

背景在长时段AI数字人直播中,商品需要按预设顺序轮换讲解,讲过的不应重复出现,未讲的应按计划上架。人工盯屏手动切换费时费力,设计一套商品自动上下架系统可以大幅降低运营成本。系统架构核心组件包括:商品队列管理器…

2026/10/9 1:39:49 阅读更多 →
保姆级实战!用宝塔部署企业级Java开源电商商城

保姆级实战!用宝塔部署企业级Java开源电商商城

一、教程简介Tigshop是拥有16年企业级电商研发经验的开源商城系统,采用SpringBoot3 Vue3 Nuxt3 UniApp主流全栈架构,全面覆盖B2C单商户、B2B2C 多商户、O2O 多门店、跨境多语言、S2B2C 供应链五大核心电商场景,是企业级商用落地首选的开源…

2026/10/14 6:25:35 阅读更多 →

最新新闻

卡尔曼滤波从原理到实战:行人多目标追踪与检测框平滑全解析

卡尔曼滤波从原理到实战:行人多目标追踪与检测框平滑全解析

目标追踪是个看着简单、做着上头的问题。想象一个监控摄像头,一个人从画面左侧走到右侧,中间被柱子挡住两秒,再出现时,系统要能认出还是同一个人,把轨迹连续画出来。就这么个场景,背后其实压着两个问题&…

2026/10/14 8:13:51 阅读更多 →
滑动窗口算法:高效解决字符串子区间问题

滑动窗口算法:高效解决字符串子区间问题

1. 滑动窗口算法核心思想解析滑动窗口(Sliding Window)是解决字符串和数组子区间问题的高效算法范式。它的核心在于维护一个动态变化的窗口,通过左右指针的协同移动来避免重复计算,将时间复杂度从暴力解法的O(n)优化到O(n)。1.1 算…

2026/10/14 8:13:51 阅读更多 →
AnyPS5项目暂无法生成技术内容

AnyPS5项目暂无法生成技术内容

项目标题是“AnyPS5”,但提供的输入内容中,项目正文为空、关键词未列出、摘要描述缺失,仅有一个孤立的标题和两行无效占位符(“相关热搜词:”“最新网络热词:”后均无实际内容),且后…

2026/10/14 8:13:51 阅读更多 →
ES6箭头函数:核心特性与最佳实践指南

ES6箭头函数:核心特性与最佳实践指南

1. 箭头函数基础概念解析箭头函数(Arrow Function)是ES6标准中引入的一种函数表达式简写语法,它用">"符号定义函数,因此得名"箭头函数"。这种语法糖的出现彻底改变了JavaScript中函数定义的书写方式。我第…

2026/10/14 8:13:51 阅读更多 →
AnyPS5:面向PS5开发的声明式工作流编排工具

AnyPS5:面向PS5开发的声明式工作流编排工具

项目标题:“AnyPS5”这个名称本身带有强烈的指向性与模糊性并存的特征——它既像一个技术代号,又像一句口号;既暗示兼容性、泛用性(“Any”),又锚定在特定硬件生态(“PS5”)。但问题…

2026/10/14 8:13:51 阅读更多 →
Spring AI Alibaba Graph:企业级AI流程编排从ReAct Agent到Workflow实战

Spring AI Alibaba Graph:企业级AI流程编排从ReAct Agent到Workflow实战

1. 从“能聊”到“能干”:企业级AI流程编排的真实痛点很多团队在2024年前后都经历过这样一个阶段:用大模型API搭一个对话机器人,演示效果惊艳,但一旦要接入真实业务系统,立刻原形毕露。用户问“帮我查一下上个月的订单…

2026/10/14 8:12:51 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →