MySQL中使用IN查询到底走不走索引

IN查询用索引,数据量小、占比低好使。
数据量过大、占比3 0%以上,全表扫,索引无用。
子查询复杂,影响索引选择,不确定效果。
你自己掂量。

不要再问我 in,exists 走不走索引了...

哎哟,这个问题咱们得好好聊聊。
前阵子咱们公司处理一个业务需求,就是要把数据A存进数据库B,然后找出B里没有的。
为了弄明白这个,我用了个模型来描述这个流程。
咱们发现,这事儿涉及到“notin”和“notexists”的逻辑,但具体怎么用,效率怎么样,还有是不是不走索引,咱们都有点迷糊。

咱们先来简单说说用法。
我举个例子,咱们有两张表,叫t1 和t2 ,主键是id,name是普通索引。
咱们要找t1 里比t2 多出来的数据,可以用“notin”或者“notexists”。
俩方法都行,但细节得注意。
比如,“notin”得保证子查询的匹配字段不能是空,要是t2 里name字段有空的,用“notin”就找不出来。
而“notexists”不管这些,只关心是不是存在匹配项。

说到执行效率,这玩意儿得看MySQL版本和数据量。
比如,“in”和“exists”用索引的情况就不一样。
一般来说,“in”先执行子查询,然后跟外部表做笛卡尔积,最后筛选结果。
而“exists”是先遍历外部表,然后对每个记录在内部表里匹配,找到匹配的就返回true。

有没有不走索引的说法?网上有些人说“in”和“exists”不走索引,其实不一定。
这得看MySQL版本和字段长度,还有数据量。
咱们实际测试了一下,发现这俩玩意儿跟数据量和字段长度有关。

再说说“exists”比“in”效率高的说法。
这个也不一定,得看数据量。
有的测试显示“exists”效率更高,但有的就不是这样。

“notin”和“notexists”哪个更快?这个得看数据量和索引类型。
一般来说,小表当外部表的时候,“notexists”效率更高,大表当外部表的时候,“notin”和“notexists”效率差不多,有时候“notin”还更快。

最后,咱们得聊聊“in”为什么能转换成“join”。
这个得从JOIN的嵌套循环说起。
JOIN有三种嵌套循环连接:简单嵌套循环连接、索引嵌套循环连接和块索引嵌套连接。
这三种连接方式复杂度和效率都不一样,用索引和缓存优化能提高效率。

哎,说这么多,其实就是想让大家明白这些操作符的用法、效率和索引使用情况。
这玩意儿得根据具体情况来,不能一概而论。