参考来源:https://www.cnblogs.com/bulushengse/p/12703789.html
结论:IN肯定会走索引,但是当IN的取值范围较大时会导致索引失效,走全表扫描
当我们执行sql:explain select * from student where sid in(1)
得到执行计划,可以看到字段type:const
type:
all:没有使用索引,全表扫描
index:全部扫描,但是使用了索引,扫描方式是按照索引的顺序
range:有范围的索引扫描,相对于index的全表扫描,它是有范围的,因此要优于index
ref:查找条件列使用了索引而且不为主键和unique。其实,意思就是虽然使用了索引,但该索引列的值并不唯一,有重复。这样即使使用索引快速查找到了第一条数据,仍然不能停止,要进行目标值附近的小范围扫描。但它的好处是它并不需要扫全表,因为索引是有序的,即便有重复值,也是在一个非常小的范围内扫描。
const:通常情况下,如果将一个主键放置到where后面作为条件查询,mysql优化器就能把这次查询优化转化为一个常量。至于如何转化以及何时转化,这个取决于优化器。
一般来说,得保证查询至少达到range级别,最好能达到ref,type出现index和all时,表示走的是全表扫描没有走索引,效率低下,这时需要对sql进行调优。
explain select * from student where sid in(1,2,3)
得到执行计划,可以看到字段type:range
explain select * from student where sid in(1,2,3,4,5,6)
得到执行计划,可以看到字段type:all
发现此时已经没有走索引了,而是全表扫描
所以回过头来看前文的一句话:IN肯定会走索引,但是当IN的取值范围较大时会导致索引失效,走全表扫描
在这篇文章最后也得出结论:
https://www.cnblogs.com/stoneFang/p/11032746.html
根据实际的情况,需要控制IN查询的范围。原因有以下几点
- IN 的条件过多,会导致索引失效,走索引扫描
- IN 的条件过多,返回的数据会很多,可能会导致应用堆内内存溢出。
所以必须要控制好IN的查询个数。