INDEX 索引管理
创建、查看和删除索引,使用 EXPLAIN 分析查询执行计划
语法
CREATE INDEX index_name ON table (column1 [, column2 ...]); ALTER TABLE table ADD INDEX index_name (columns); DROP INDEX index_name ON table; EXPLAIN SELECT ...;
参数
| 参数 | 说明 | 示例 | 级别 |
|---|---|---|---|
CREATE INDEX |
创建普通索引 | CREATE INDEX idx_email ON users(email); |
常用 |
UNIQUE INDEX |
创建唯一索引 | CREATE UNIQUE INDEX uk_phone ON users(phone); |
常用 |
SHOW INDEX |
查看表的索引信息 | SHOW INDEX FROM users; |
常用 |
DROP INDEX |
删除索引 | DROP INDEX idx_email ON users; |
常用 |
EXPLAIN |
分析查询执行计划 | EXPLAIN SELECT * FROM users WHERE email = 'a@b.com'; |
常用 |
FULLTEXT |
全文索引 | CREATE FULLTEXT INDEX ft_title ON articles(title, content); |
进阶 |
示例
创建复合索引
-- 遵循最左前缀原则 CREATE INDEX idx_status_created ON orders(status, created_at);
查询条件包含 status 或 status+created_at 时生效
EXPLAIN 分析慢查询
EXPLAIN SELECT o.*, u.username FROM orders o JOIN users u ON o.user_id = u.id WHERE o.status = 1 ORDER BY o.created_at DESC LIMIT 20;
关注 type(最好 ref/range)、key(使用的索引)、rows(扫描行数)
查看索引使用情况
SHOW INDEX FROM orders; -- 查看索引基数 SELECT INDEX_NAME, COLUMN_NAME, CARDINALITY FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 'orders';
CARDINALITY 越高说明索引区分度越好
覆盖索引优化
-- 创建覆盖索引,查询不需要回表 CREATE INDEX idx_cover_order ON orders(user_id, status, created_at, total_amount); -- 这个查询只需要索引就能完成 SELECT status, created_at, total_amount FROM orders WHERE user_id = 1001;
EXPLAIN 中 Extra 显示 Using index 表示覆盖索引生效
常见错误
ERROR 1061 (42000): Duplicate key name 'idx_xxx'
索引名已存在,换一个名字或先删除旧索引
EXPLAIN 显示 type=ALL(全表扫描)
查询没有命中索引。检查 WHERE 条件是否有对应索引,是否使用了函数导致索引失效
技巧
- 索引不是越多越好,每个索引都会降低写入速度
- 复合索引遵循最左前缀原则:(a,b,c) 索引对 WHERE a=1 和 WHERE a=1 AND b=2 有效
- WHERE 条件中对列使用函数会导致索引失效:WHERE YEAR(created_at) = 2026 应改为范围查询