Laravel MySQL普通索引无提速、全文索引提速明显的原因
普通索引未生效、全文索引提速明显的核心原因
你当前操作的几个核心误区
- 你创建的索引完全没匹配查询场景:你在迁移代码里写的是
$table->integer('id')->index();,是给id字段加索引,但你实际查询的WHERE筛选条件根本没有用id做过滤,索引自然完全不会被调用,加了和没加没有任何区别。 - 给
id字段加普通索引本身就是无效操作:正常Laravel项目里的id是表主键,自带聚簇主键索引,查询时走主键索引的效率远高于你额外创建的普通二级索引,数据库优化器会直接忽略你这个重复的冗余索引,根本不会使用。 - 表数据量级决定了普通索引很难体现优势:你的表总共只有5000条记录,这个数据规模下,哪怕你给正确的筛选字段加了索引,数据库优化器也大概率会选择全表扫描——因为走二级索引需要先遍历索引树、再回表查询完整行数据,开销比直接顺序扫描全表还高,自然不会有速度提升。
- 1秒的查询耗时本身就不符合小表的正常表现:5000条记录就算全表扫描,正常耗时也应该在几毫秒级别,能跑到1秒说明你的查询本身有其他问题,比如对筛选字段做了函数运算导致无法命中索引、多表连表没给关联字段加索引、查询了大量不必要的大字段、存在锁等待等,和你给id加没加索引没关系。
全文索引提速4倍的原因
全文索引和你创建的普通B树索引适用场景完全不同:
- 普通B树索引只能对前缀匹配的查询生效,比如
where name like '关键词%',如果是做文本模糊搜索(比如where content like '%关键词%'),普通B树索引完全失效,只能逐行扫描全表做文本匹配,开销极高。 - 全文索引是专门为文本检索设计的倒排索引,会提前把文本内容分词后构建索引映射,查询时不需要逐行扫描匹配,直接通过倒排链表定位符合条件的记录,刚好匹配你另一个项目的文本搜索场景,所以速度提升非常明显。
正确的优化方式
- 删掉给id加的冗余普通索引,主键自带的索引已经足够覆盖所有id相关的查询。
- 找到你实际查询中WHERE条件、ORDER BY排序、JOIN关联用到的字段,给这些字段创建对应索引,不要随便给无关字段加索引。
- 执行查询前用
EXPLAIN关键字查看执行计划,确认key字段显示了你创建的索引、rows字段显示的扫描行数和你实际返回的600条接近,才说明索引真的被用上了。 - 如果是文本类的模糊搜索场景,不要用普通B树索引,直接用全文索引或者专门的搜索引擎才是正确方案。
注意:不要觉得加了索引就一定会提速,索引只有匹配查询场景、且优化器判断走索引的开销低于全表扫描时,才会真正生效。
内容的提问来源于stack exchange,提问作者web pakistan
相关产品推荐
相关产品推荐

