最近在图书管理系统做查询接口的时候发现,明明给图书名称加了索引,模糊查询的时候依然走全表扫描。借此机会整理一份 MySQL 索引避坑清单。
常见失效场景:
like '%关键词',前置百分号会导致索引失效;- 在索引列上做函数运算;
- 隐式类型转换,字符串字段传入数字;
- 使用 or,一边有索引一边没有;
- 联合索引不满足最左前缀原则。
举个反面例子:
-- 索引失效
select * from book where name like '%Java';
-- 可以走索引
select * from book where name like 'Java%';
如果业务必须做全文检索,单纯 B+Tree 索引并不合适,可以考虑 Elasticsearch,或者阿里云的全文检索服务。
另外,很多新人喜欢给每一个字段单独建索引,这是不对的。索引会加快查询,但是会降低插入、更新速度,占用磁盘空间。优先根据高频查询建立联合索引,并且使用 explain 查看执行计划,不要凭感觉优化。
在实际项目中,优先优化慢查询,而不是上来就疯狂加索引。可以开启慢查询日志,把耗时超过阈值的 SQL 捞出来逐个分析。