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

MySQL 索引学习全景笔记

下面给出一份「看完就能落地」的 MySQL 索引学习全景文章,覆盖
①索引概述 → ②索引结构 → ③索引分类 → ④索引语法 → ⑤SQL 性能分析 → ⑥索引使用实战 → ⑦设计原则与踩坑,
并穿插「随手笔记 + 可运行代码 + 完整案例」,一条线学透。


  1. 索引概述(是什么 & 为什么)
  • 定义:索引是排好序的、帮助快速检索数据的数据结构,存储在磁盘,由存储引擎层实现。
  • 类比:字典音序表、书籍目录。
  • 代价:占用磁盘空间、降低 DML 速度(需要同步维护)。
  • 权衡:OLTP 场景“读 >> 写”,合理索引 ROI 极高。

代码感受 10 万行差距

-- 建表时故意不加索引
CREATE TABLE t_user(id INT PRIMARY KEY,          -- 只有主键索引name VARCHAR(50),age  INT
);
INSERT INTO t_user SELECT * FROM t_user;  -- 重复插入到约 10 万行-- 无索引全表扫描
mysql> SELECT * FROM t_user WHERE age=30;
+------+------+------+
| id   | name | age  |
+------+------+------+
... 1000-- 耗时 0.12 s-- 对 age 建普通索引
ALTER TABLE t_user ADD INDEX idx_age(age);-- 同样语句
-- 耗时 0.001 s(120 倍差距)

结论:索引是“空间换时间”的典型工程实践。


  1. 索引结构(底层长什么样)
    2.1 主流结构对比
结构特点引擎支持适用场景
B+Tree(多路平衡树)有序、范围查询友好、扇出高、IO 少InnoDB/MyISAM 默认95% 场景
Hash仅 = 查询、O(1)、无序Memory 引擎显式支持等值热点缓存
R-Tree空间索引MyISAMGIS
Full-text倒排InnoDB≥5.6大文本关键词

2.2 为什么选 B+Tree

  • 高度低:1 000 万行仅 3-4 层 → 3-4 次 IO。
  • 叶子双向链表:范围扫描无需回溯。
  • 非叶子节点只存键 → 一个页(16 KB)可存 1 200+ 键,扇出大。

手绘 3 层 B+Tree 示意图(文字版)

 [10 |  20 |  30  |  40  |  50 ]          ← 根(非叶子)/      |      |    |     \
[1-9][10-19][20-29][30-39][40-50]  ← 叶子(含行/主键)
↑→ 双向指针 →↑

  1. 索引分类(面试常考)

  2. 按逻辑

    • 主键索引(PRIMARY)
    • 唯一索引(UNIQUE)
    • 普通索引(KEY / INDEX)
    • 全文索引(FULLTEXT)
    • 组合索引(复合索引)
    • 前缀索引(对 TEXT/VARCHAR 前 N 字符)
  3. 按物理

    • 聚簇索引(Clustered):叶子=整行数据,InnoDB 必有,只能有一个。
    • 二级索引(Secondary):叶子=主键值,需要回表
  4. 按数据结构
    B+Tree、Hash、R-Tree、Full-text。


  1. 索引语法(速查表)
-- 1. 建表时一起建
CREATE TABLE article(id INT PRIMARY KEY,                       -- 聚簇user_id INT NOT NULL,title VARCHAR(200),content TEXT,UNIQUE uk_user_title(user_id,title),      -- 组合唯一INDEX idx_user(user_id),                  -- 普通FULLTEXT ft_content(content)              -- 全文
) ENGINE=InnoDB;-- 2. 事后加
ALTER TABLE article ADD INDEX idx_ctime(create_time);
CREATE INDEX idx_title ON article(title(20)); -- 前缀-- 3. 查看
SHOW INDEX FROM article\G-- 4. 删除
DROP INDEX idx_user ON article;
ALTER TABLE article DROP INDEX uk_user_title;

  1. SQL 性能分析工具箱
  1. 执行计划 EXPLAIN(最常用)
EXPLAIN SELECT * FROM article WHERE user_id=123\G

关键字段

  • type:ALL(全表) < index < range < ref < eq_ref < const
  • key:实际用到的索引
  • rows:预估扫描行数
  • Extra:Using index(覆盖)、Using filesort(需排序)、Using temporary(临时表)
  1. 优化器 trace(看选索引过程)
SET optimizer_trace="enabled=on";
SELECT ...;                 -- 你的SQL
SELECT * FROM information_schema.optimizer_trace\G
SET optimizer_trace="enabled=off";
  1. 会话级 profiling(简单耗时)
SET profiling=1;
SELECT ...;
SHOW PROFILE FOR QUERY 1;
  1. 官方 Performance Schema(生产推荐)
UPDATE performance_schema.setup_consumers
SET enabled='YES' WHERE name LIKE '%statements%';
-- 查询最耗时 SQL
SELECT DIGEST_TEXT, COUNT_STAR, AVG_TIMER_WAIT/1e9 AS avg_ms
FROM events_statements_summary_by_digest
ORDER BY SUM_TIMER_WAIT DESC LIMIT 5\G

  1. 索引使用实战(正反面案例)
    案例 1 覆盖索引减少回表
    需求:订单表 2 000 万行,常按 user_id 查订单号。
-- 表结构
CREATE TABLE orders(id BIGINT PRIMARY KEY,user_id INT,order_no VARCHAR(32),amount DECIMAL(10,2),status TINYINT,create_time DATETIME
);-- 最初只有主键,查询
SELECT order_no FROM orders WHERE user_id=12345;
-- type=ALL  2 s-- 建组合索引并覆盖
ALTER TABLE orders ADD INDEX idx_user_no(user_id, order_no);
-- 同样语句 type=ref  Extra=Using index  10 ms

Explain 对比

key: idx_user_no
rows: 80
Extra: Using index   -- 无需回表

案例 2 最左前缀失效

ALTER TABLE orders ADD INDEX idx_u_s(user_id, status);-- 能用到
SELECT * FROM orders WHERE user_id=123;
SELECT * FROM orders WHERE user_id=123 AND status=1;-- 用不到
SELECT * FROM orders WHERE status=1;      -- 跳过最左列

案例 3 范围列后断组合索引

INDEX idx_range(user_id, create_time, order_no)-- 只用前两列
SELECT * FROM orders
WHERE user_id=123AND create_time BETWEEN '2025-01-01' AND '2025-01-31'AND order_no='N123';   -- 第三列失效

案例 4 隐式转换导致索引失效

-- order_no 是 varchar,但用数字
SELECT * FROM orders WHERE order_no=200601019999;  
-- 会隐式 CAST(col AS DECIMAL) → 函数包裹 → 索引失效
-- 改为字符串
SELECT * FROM orders WHERE order_no='200601019999';

案例 5 索引下推(ICP)
Extra 出现 Using index condition 代表引擎层先过滤,减少回表。

INDEX idx_user_status(user_id, status)SELECT * FROM orders
WHERE user_id BETWEEN 10000 AND 20000AND status=1;

  1. 索引设计原则(checklist)
  2. 数据量 > 1 000 行 & 查询频次 > 更新频次 → 值得建。
  3. 选择性公式:SELECT COUNT(DISTINCT col)/COUNT(*) > 0.2 越高越好。
  4. 联合索引把选择性高的放最左;范围列放最后。
  5. 覆盖索引优先:让 Extra 出现 Using index。
  6. 控制总数:单表建议 ≤ 6 个二级索引;过多会拖慢写入。
  7. 长文本用前缀索引:ALTER TABLE tb ADD INDEX idx_url(url(64));
  8. 业务唯一列一定加 UNIQUE,既保数据又送索引。
  9. 禁止对“性别/状态”这类低选择度列单独建索引。
  10. 线上大表加索引用 pt-online-schema-changegh-ost,避免锁表。
  11. 发布前 EXPLAIN 所有新 SQL,拒绝 ALL 和 Using filesort。

  1. 小结脑图(文字版)
MySQL 索引
├─ 概述:排好序的快速查找结构,空间换时间
├─ 结构:B+Tree 为主,Hash/R-Tree/Full-text 为辅
├─ 分类:主键/唯一/普通/组合/前缀/全文/聚簇/二级
├─ 语法:CREATE/ALTER/DROP + SHOW INDEX
├─ 性能分析:EXPLAIN → trace → PFS
├─ 实战:覆盖/最左/范围/隐转/ICP
└─ 设计:高选择性、最左、覆盖、控制个数、在线工具

把本文 SQL 全部跑一遍,你会得到:

  • 120 倍提速的直观体验
  • 一份属于自己的 EXPLAIN 清单
  • 不再怕“索引失效”面试追问。

Happy indexing!


文章转载自:

http://ackj7sVh.ghxkm.cn
http://bnfDVvJn.ghxkm.cn
http://xKWfYZZL.ghxkm.cn
http://CLEdcfUp.ghxkm.cn
http://Q59TY2mC.ghxkm.cn
http://AKUOd0hS.ghxkm.cn
http://jFVBXFzJ.ghxkm.cn
http://RxiJp3Za.ghxkm.cn
http://cqErKoT5.ghxkm.cn
http://yYKGTsgq.ghxkm.cn
http://42p5kLmm.ghxkm.cn
http://BR2RABDu.ghxkm.cn
http://rQgrstkn.ghxkm.cn
http://GopVQLX2.ghxkm.cn
http://Ulw7bHQR.ghxkm.cn
http://6TIW665g.ghxkm.cn
http://5uVSPeQ9.ghxkm.cn
http://EoQ0NP5X.ghxkm.cn
http://uEhpBi1b.ghxkm.cn
http://LZtTIoMp.ghxkm.cn
http://FWSlWxbf.ghxkm.cn
http://ZEmytAKG.ghxkm.cn
http://ZEc5lPmY.ghxkm.cn
http://2ykW05LF.ghxkm.cn
http://yMoN4KLK.ghxkm.cn
http://dYKHSoud.ghxkm.cn
http://omfpdLhs.ghxkm.cn
http://78BiNblJ.ghxkm.cn
http://wP10VjQS.ghxkm.cn
http://vXciE3WN.ghxkm.cn
http://www.dtcms.com/a/380545.html

相关文章:

  • Ethernaut Foundry Solutions - 完整系列教程
  • 【ARDUINIO】从串口读取数据的方法总结
  • Redis环境搭建指南:Windows/Linux/Docker多场景安装与配置
  • 如何使用 Linux ping 命令 ?
  • 分布式专题——10.3 ShardingSphere实现原理以及内核解析
  • 神经网络稀疏化设计构架方法和原理深度解析
  • 10-SpringBoot入门案例(下)
  • ⽹络请求Axios的概念和作用
  • 缓存三大劫攻防战:穿透、击穿、雪崩的Java实战防御体系(三)
  • 认知语义学对人工智能自然语言处理的深层语义分析:理论启示与实践路径
  • 快速搭建B/S架构HTML演示页:从工具选择到实战落地
  • Git 简介
  • Java 中 Word 文档的加密与解密
  • SAM-Med3D:面向三维医疗体数据的通用分割模型 (代码仓库笔记)
  • 嵌入式桌面集成 · GNOME 与 Yocto 在 Jetson AGX Orin 上的实战指南
  • Model Context Protocol (MCP) 安全风险与攻击方式解析
  • 计算机毕业设计 基于大数据技术的医疗数据分析与研究 Python 大数据毕业设计 Hadoop毕业设计选题【附源码+文档报告+安装调试】
  • 单片机烧录原理是怎样的?辉芒微单片机烧录程序步骤教程如下
  • CI/CD流水线优化实战:从30分钟到5分钟的效能革命
  • 融智学:构建AI时代学术的新范式
  • 自指与递归既是威力也是边界(会带来不可判定与不完备)
  • HarmonyOS 实战:如何用数据压缩和解压让应用更快更省
  • 软考-系统架构设计师 信息安全的抗攻击技术详细讲解
  • Spring Initializr(或者 IDEA 里新建 Spring Boot 项目)时 Dependencies 的选择
  • 创建一个Spring Boot Starter风格的Basic认证SDK
  • 数据库的连接_qt
  • Tessent_ijtag_ug——第 4 章 ICL 提取(1)
  • Qt开发经验 --- Qt 修改控件样式的方式(16)
  • UE5 基础应用 —— 07 - 角色蓝图 简单使用
  • Motioncam Color S + 蓝激光:3D 视觉革新,重塑工业与科研应用新格局