当前位置: 首页 > 后端技术 > Java

为什么MySQL查询没有索引?本文带你全面解析

时间:2023-04-02 09:51:59 Java

作品。我经常遇到这样的问题。我在MySQL表中添加了一个索引。为什么执行SQL查询时没有使用索引?同一个SQL查询有时使用索引,有时不使用索引。怎么了?原因可能是索引无效。失败的原因有多种。你踩过类似的坑吗?1.数据准备:有这么一张user表,在name字段上建索引:CREATETABLE`user`(`id`intNOTNULLAUTO_INCREMENTCOMMENT'primarykey',`name`varchar(255)DEFAULTNULLCOMMENT'name',`age`intDEFAULTNULLCOMMENT'age',PRIMARYKEY(`id`),KEY`idx_name`(`name`))ENGINE=InnoDBCOMMENT='usertable';2.详细解释:我想查看一个SQL是否使用索引?使用什么类型的索引?您可以使用explain关键字查看SQL执行计划。例如:解释select*fromuserwhereid=1;可以看到type=const,说明使用了主键索引。所有类型类型解释如下:三、失败原因1、数据类型隐式转换名称字段为varchar类型,如果我们使用数据类型查询,会发生数据类型转换,虽然不会报错,但是索引不能使用。解释select*fromuserwherename='Yideng';解释select*fromuserwherename=18;2。模糊查询likestartwith%explainselect*fromuserwherenamelike'Zhang%';explainselect*fromuserwherenamelike'%zhang';3、or前后没有索引。虽然名字字段有索引,但是年龄字段没有索引。使用or时,将扫描整个表。#或者前后没有同时使用索引,导致全表扫描explainselect*fromuserwherename='Yileng'orage=18;4.联合索引没有使用首列索引如果我们在(name,age)上,创建联合索引,但是查询条件中只使用了age字段,无法使用索引。使用联合索引时,必须遵循最左匹配原则,先使用第一列字段,再使用第二列字段。CREATETABLE`user`(`id`intNOTNULLAUTO_INCREMENTCOMMENT'primarykey',`name`varchar(255)DEFAULTNULLCOMMENT'name',`age`intDEFAULTNULLCOMMENT'age',PRIMARYKEY(`id`),KEY`idx_name_age`(`name`,`age`))ENGINE=InnoDBCOMMENT='usertable';5.对索引字段进行计算如果我们对索引列进行计算,那么索引就不能使用了。#对主键索引进行计算,产生全表扫描explainselect*fromuserwhereid+1=2;6.在索引字段上使用函数如果我们在索引列上使用函数,就不能使用索引。7.优化器选择了错误的索引。同一个SQL查询有时使用索引,有时不使用索引。怎么了?这可能是优化器选择的结果,优化器会根据表的数据量来选择是否使用索引。当表中大部分名字都是一灯,用name='一灯'查询时,会用到索引吗?索引优化器会认为使用索引不如全表扫描快,所以根本不使用索引。当然,我们认为是优化器出错了,我们也可以使用forceindex来强制使用索引。知识点总结:文章持续更新中。可以在微信搜索“一光架构”第一时间阅读更多技术干货。