MySQL 索引是数据库性能优化里最基础也最重要的内容之一。一个查询慢,不一定是服务器配置不够,很多时候只是没有合适索引,或者索引用错了。
索引可以帮助 MySQL 更快找到数据,但索引不是越多越好。它会占用存储空间,也会影响写入和更新性能。本文从普通索引、唯一索引和联合索引讲起,再整理常见优化思路和误区。
索引是什么
索引可以理解为数据表的目录。没有索引时,MySQL 可能需要从头到尾扫描整张表;有了合适索引,就能更快定位符合条件的记录。
SELECT * FROM users WHERE email = 'demo@example.com';
如果 email 字段有索引,查询通常会更快。尤其是数据量从几千增长到几十万、几百万后,索引的作用会非常明显。
普通索引
普通索引是最基础的索引类型,允许字段值重复。比如文章分类、用户状态、创建时间等字段都可以根据查询需求建立普通索引。
CREATE INDEX idx_status ON users(status);
普通索引适合加速查询,但是否值得建立,要看字段选择性和查询频率。如果某个字段只有很少几个值,比如性别、布尔状态,单独建索引不一定收益明显。

唯一索引
唯一索引用来保证字段值不能重复,同时也能提升查询速度。常见场景包括用户名、邮箱、手机号、订单号等业务唯一字段。
CREATE UNIQUE INDEX uniq_email ON users(email);
唯一索引不仅是性能工具,也是数据约束。比如邮箱注册不能重复,只靠代码判断可能有并发问题,数据库唯一索引能提供更可靠的兜底。
主键索引
主键是一种特殊的唯一索引,并且不能为空。MySQL InnoDB 表通常会围绕主键组织数据,因此主键设计会影响查询和写入性能。
CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(255) NOT NULL
);
常见做法是使用自增 ID 或有序 ID 作为主键。过于随机的主键可能增加页分裂和写入成本。
联合索引
联合索引是多个字段组成的索引,适合多条件查询。比如后台经常按状态和创建时间查询文章列表,可以建立联合索引。
CREATE INDEX idx_status_created ON articles(status, created_at);
联合索引字段顺序很重要。它不是简单地等于给每个字段都建了索引,而是按从左到右的顺序组织。
最左前缀原则
联合索引遵循最左前缀原则。假设索引是 (status, created_at, id),那么查询条件从 status 开始匹配时更容易利用索引。
WHERE status = 'published' ORDER BY created_at DESC
如果查询完全跳过最左侧字段,只按 created_at 查询,这个联合索引未必能充分发挥作用。设计联合索引前,要先看真实 SQL。
覆盖索引
如果查询需要的字段都在索引里,MySQL 可以直接从索引中拿到结果,减少回表,这叫覆盖索引。
CREATE INDEX idx_status_title ON articles(status, title);
SELECT title FROM articles WHERE status = 'published';
覆盖索引可以提升部分查询性能,但不要为了覆盖所有字段建立特别大的索引。索引越宽,维护成本越高。
索引失效
索引不是建了就一定会用。常见失效原因包括在索引字段上使用函数、隐式类型转换、前置通配符 LIKE、查询条件选择性太低等。
WHERE DATE(created_at) = '2026-05-06'
这种写法对字段使用函数,可能导致索引难以使用。更好的方式是改成范围查询。
WHERE created_at >= '2026-05-06 00:00:00'
AND created_at < '2026-05-07 00:00:00'
LIKE 查询
LIKE 查询是否能用索引,取决于通配符位置。后置通配符通常还能利用索引,前置通配符通常难以利用普通 B-Tree 索引。
WHERE title LIKE 'PHP%'
WHERE title LIKE '%PHP%'
第二种包含查询更适合全文索引或搜索服务。不要指望普通索引解决所有模糊搜索问题。
查看执行计划
优化索引时要使用 EXPLAIN 查看执行计划,而不是凭感觉判断。
EXPLAIN SELECT * FROM articles WHERE status = 'published';
重点关注 type、key、rows、Extra 等字段。它们能帮助判断是否使用索引、扫描行数是否过多、是否出现文件排序等情况。
不要乱建索引
索引会提升查询,但会拖慢写入。每次插入、更新、删除数据时,MySQL 都要维护相关索引。索引太多还会占用更多磁盘和内存。
因此索引应该围绕高频查询、慢查询和唯一约束来设计,而不是给每个字段都加一遍。
常见错误
第一种错误是数据量很小时就过度建索引。第二种错误是联合索引字段顺序随便排。第三种错误是给低选择性字段单独建索引却没收益。第四种错误是建了索引却在查询里对字段使用函数。第五种错误是不看 EXPLAIN。
实践建议
设计索引前,先收集真实 SQL。单字段高频查询可以考虑普通索引;业务唯一字段用唯一索引;多条件查询和排序场景考虑联合索引;慢查询要结合 EXPLAIN 分析。
MySQL 索引优化不是把索引数量堆上去,而是让少量关键索引覆盖核心查询。索引用得准,比用得多更重要。













暂无评论内容