MySQL 索引与 SQL 优化

返回 面试 · 数据库总览 数据库常见面试题

详解 索引索引与失效SQL优化


为什么 B+ 树

结构问题
哈希不支持范围、排序
二叉树可能退化成链,IO 高
B+ 树矮树、叶链表、范围扫描友好

InnoDB:主键 = 聚簇索引,叶节点存完整行。


聚簇 vs 二级索引

聚簇索引二级索引
数量每表 1 个可多个
叶节点完整行主键值
查询通常需 回表

覆盖索引:查询列全在索引中 → Using index,无需回表。


最左前缀

联合索引 (a, b, c)

SQL 条件能否用索引
a
a, b
a, b, c
b, c❌ 跳过 a
a, c⚠️ 只用到 a

索引失效(常见)

情况原因
对列 函数/运算WHERE YEAR(d)=2024
隐式类型转换字符串列比数字
左模糊LIKE '%abc'
OR 一侧无索引可能全表
优化器判全表更快小表、选择性差
不符合最左前缀见上

EXPLAIN 看什么

关注
typeALL 全表差;range/ref/const 较好
key实际用的索引
rows预估扫描行数
ExtraUsing index 覆盖;Using filesort/Using temporary 需优化

EXPLAIN与运维


SQL 优化思路

  1. 慢查询日志 定位 SQL
  2. EXPLAIN 看是否走索引
  3. 加/改索引(覆盖、最左、选择性高的列在前)
  4. 避免 SELECT *
  5. 深分页:WHERE id > lastId LIMIT n 代替大 offset
  6. 批量写、减少锁范围

主键选型

自增整型UUID
插入顺序追加,少页分裂随机,分裂多
推荐InnoDB 首选分布式 ID 可用 Snowflake

常见面试题

Q:索引是不是越多越好?
A:否;写要维护索引,占空间;按查询路径建,删除冗余索引。

Q:唯一索引 vs 普通索引?
A:唯一索引插入需判重,略慢;都能加速查询。

Q:前缀索引?
A:INDEX(name(10)) 省空间;无法覆盖排序/Group By 全列。

Q:慢 SQL 怎么排查?
A:slow_query_log → EXPLAIN → 索引/改写 SQL → 验证 rows 与耗时。


相关笔记