MySQL 中 EXISTS 和 IN 的区别是什么?
MySQL 中 EXISTS 和 IN 的区别是什么?
回答重点
基本功能:
EXISTS用于判断子查询是否返回任何行,通常用于检查某个条件是否满足。IN用于检查某个值是否在指定的集合中,可以是一个子查询或静态值列表。
性能差异:
EXISTS一旦找到匹配行就会立即返回,通常在子查询返回较大数据集时性能更好。IN通常会评估整个子查询并构建一个值列表,然后再进行匹配,在处理较大数据集时可能性能较差。
使用场景:
EXISTS更适合用于大数据量或复杂逻辑的条件判断。IN更适合简单的静态值集合或较小的子查询结果。
扩展知识
进一步分析 EXISTS 和 IN 性能问题
EXISTS
EXISTS 的查询机制是循环外表,通过外表的每行数据去内表查询是否有匹配的值,一旦找到符合条件的记录,此次内表子查询就会停止执行。然后再通过下一个外表的值来查询,如此循环。
1 | SELECT * FROM `mianshiya` |
例如 mianshiyia 表有 100 条数据,order有 10000 条数据,那么 EXISTS 会执行 100 次去 order 中查询判断 mianshiyia的 user_id 和 order user_id 是否相等。
所以它适合子查询中表比外表大且有索引的场景。
IN
而 IN 子查询在执行时会先执行子查询并生成结果集,然后将结果集与外部查询的列进行比较,所以它适合子查询记录少,且主查询表大有索引的场景。
1 | SELECT * FROM `mianshiya` |
同样 mianshiyia_user 表有 100 条数据,order有 10000 条数据,那么 in 操作会先执行子查询获取 order 的 10000 条数据这个结果集放在缓存中。
如果 mianshiyia_user user_id 上有索引则可以利用索引查询,不然就是逐行检查 mianshiyia_user 中的 user_id 是否与结果集中的 user_id 一致执行,因此一共会进行 100*10000 次对比。
如果子查询得到的结果比较大,还会将子查询的结果存储在哈希表中,这样就能快速匹配数据。
简单总结:
- 外层查询表量级小于子查询表,且子表有索引,则用 exists
- 外层查询表量级大于子查询表,且外层表有索引,则用 in
- 如果外层和子查询表差不多,则都行。
建议具体情况还是以 explain 分析为主。
Comments