# MySQL 索引优化
# 索引类型
普通索引(INDEX)
- 最基本的索引类型
- 没有唯一性限制
CREATE INDEX index_name ON table_name (column_name);
唯一索引(UNIQUE)
- 确保列中的值是唯一的
- 可以包含NULL值
CREATE UNIQUE INDEX index_name ON table_name (column_name);
主键索引(PRIMARY KEY)
- 特殊的唯一索引
- 不允许NULL值
ALTER TABLE table_name ADD PRIMARY KEY (column_name);
复合索引(Composite Index)
- 多列组成的索引
- 遵循最左前缀原则
CREATE INDEX index_name ON table_name (col1, col2, col3);
全文索引(FULLTEXT)
- 用于全文搜索
- 只支持CHAR、VARCHAR和TEXT列
CREATE FULLTEXT INDEX index_name ON table_name (column_name);
# 索引设计原则
选择合适的列建立索引
- 经常用于查询的列
- 经常用于连接的列
- 经常用于排序的列
索引列的选择性
- 选择性越高,索引效果越好
- 计算选择性:COUNT(DISTINCT column_name) / COUNT(*)
前缀索引
- 对于长字符串列,可以只索引开始的部分
CREATE INDEX index_name ON table_name (column_name(length));
避免过多索引
- 索引会占用存储空间
- 影响插入、更新和删除性能
- 合理使用复合索引代替单列索引
# 索引使用优化
EXPLAIN分析
EXPLAIN SELECT * FROM users WHERE name = 'John';
避免索引失效的情况
- 避免在索引列上使用函数
- 避免隐式类型转换
- 注意最左前缀原则
- 避免使用NOT IN和!=
覆盖索引
- 查询的列都包含在索引中
- 可以避免回表查询
-- 好的例子 SELECT id, name FROM users WHERE name = 'John'; -- name列上有索引,包含了id和name
强制索引
SELECT * FROM users FORCE INDEX (index_name) WHERE age > 20;
# 索引维护
定期分析表
ANALYZE TABLE table_name;
重建索引
ALTER TABLE table_name DROP INDEX index_name; ALTER TABLE table_name ADD INDEX index_name (column_name);
监控索引使用情况
SHOW INDEX FROM table_name;
# 最佳实践
定期检查和优化
- 使用EXPLAIN分析查询计划
- 监控索引使用情况
- 删除不必要的索引
合理使用复合索引
- 遵循最左前缀原则
- 考虑查询模式
- 优化索引顺序
注意索引维护成本
- 权衡查询性能和维护成本
- 避免过度索引
- 定期优化和重建索引