mysql数据库中索引的基本概念_mysql索引入门解析

来源:这里教程网 时间:2026-02-28 20:44:57 作者:

索引是什么:数据库里的“目录”

索引不是数据本身,而是对数据位置的快速映射——就像书本末尾的索引页,查“B树”不用翻遍全书,直接跳到第42页。MySQL 中,

INDEX
本质是一棵有序的数据结构(多数是 B+ 树),存储的是字段值 + 对应的主键或行指针。

没索引时,

SELECT * FROM users WHERE name = 'Alice'
可能触发全表扫描;加了
INDEX(name)
后,引擎能直接定位匹配行,I/O 次数大幅下降。

什么时候必须建索引:WHERE、ORDER BY、JOIN 的常见场景

以下情况不建索引,性能容易掉坑里:

WHERE
条件中高频出现的列,尤其是选择性高(重复值少)的字段,比如
user_id
email
ORDER BY created_at DESC
—— 如果经常按时间倒序查最新10条,
INDEX(created_at)
能避免文件排序(
Using filesort
JOIN
的关联字段,如
orders.user_id
关联
users.id
,两边都建议有索引,否则驱动表小也扛不住被扫十几万次
注意:
LIKE 'abc%'
可走索引,但
LIKE '%abc'
LIKE '%abc%'
基本失效(除非用全文索引)

复合索引怎么写:最左前缀原则不是玄学

INDEX(a, b, c)
实际上等价于三个索引:
(a)
(a,b)
(a,b,c)
,但不包含
(b)
(b,c)
。这意味着:

WHERE a = 1 AND b = 2
✅ 走索引
WHERE a = 1 ORDER BY c
✅ 可能用上索引做排序(覆盖
a,c
WHERE b = 2
❌ 不走索引(跳过了最左列
a
如果查询常带
WHERE status = ? AND created_at > ?
,把区分度高的放前面更稳,比如
INDEX(status, created_at)
比反过来更有效

索引不是越多越好:维护成本和隐式陷阱

每多一个索引,INSERT/UPDATE/DELETE 都要同步更新 B+ 树,写放大明显。更隐蔽的问题包括:

字符串字段没指定长度就建索引:如
VARCHAR(255)
直接
INDEX(content)
,MySQL 默认取前 767 字节(utf8mb4 下约 191 字符),可能截断导致索引失效
频繁
UPDATE
的字段建索引,会引发大量页分裂和碎片,
SHOW INDEX FROM tbl
查看
Cardinality
是否严重偏低
唯一性低的字段(如
gender
只有 'M'/'F')建普通索引意义很小,优化器大概率直接放弃使用

真正难的不是建索引,是判断哪些查询值得索引、哪些该用覆盖索引、哪些其实该改 SQL 或加缓存——执行计划(

EXPLAIN
)里那几行
type
key
才是关键线索。

相关推荐