Mysql查询条件为大于时,竟然不走索引失效?

这就是坑,别信“范围查询一定走索引”。

mysql中in会用索引吗

哈,这个问题得好好说说。
上周有个客人问我,MySQL里的IN操作符到底什么时候会用到索引,什么时候又不会。
我就跟他说,这事儿得看情况。

首先,你要知道,当IN列表里的值比较少,比如就是几个离散的数字或者是一个主键,这时候MySQL的优化器就会选择用索引扫描。
你看,WHERE id IN (1 ,2 ,3 )这样的查询,它就会通过B+树索引进行区间查找,效率比全表扫描高多了。
执行计划里的type字段会显示为range,这表明它是通过索引来检索数据的。

但是,如果IN列表里的值太多,比如超过了优化器的阈值,或者超过了全表数据的2 0%以上,那MySQL的优化器就会觉得用索引扫描的成本太高,不如直接全表扫描。
这时候type字段会显示为ALL,rows字段会接近表的总行数,extra字段可能会出现Using where提示,意思是需要回表过滤数据。

还有几个特殊的情况,比如NOT IN条件会强制全表扫描,因为MySQL需要逐行检查数据是否不在列表中,这就不利用索引的有序性了。
复合索引也有局限性,如果你IN条件里的值不是复合索引的首列,比如索引是(a,b),而你用的是b IN (...),那这个索引就派不上用场了。

还有,IN列表里的值要和数据列的类型匹配,不然会出现隐式转换,导致索引失效。

如果你遇到大范围的IN查询,可以考虑用临时表关联或者分批查询,这样能减少单次查询对索引的压力。

最后,你可以用EXPLAIN分析执行计划,看看type字段是不是range,key字段有没有显示索引名,rows字段预估扫描行数是多少,extra字段有没有出现Using filesort或Using temporary。
如果发现索引失效了,你可能需要调整IN列表的大小或者重构你的查询逻辑。
反正你看着办,这些技巧能帮你优化查询效率。
我还在想这个问题,以后可能还得再深入了解一下。