NOT IN 慢的原因
如果在 NOT IN
子句中包含的列表非常大,查询性能可能会下降。每个要排除的值都需要逐一与查询结果进行比较,这在大数据集上可能会导致性能问题。
NOT IN 是不走索引的,需要一一比较
IN 操作
当使用 IN
子句时,数据库优化器会尝试将其转换为更高效的操作,如使用 HASH JOIN
或 MERGE JOIN
等技术来处理。这些技术可以通过创建临时哈希表或排序表来加快查询速度。优化器会尝试选择最佳的执行计划,以减少比较操作的次数,并利用索引等数据结构来加速查询。
此外,IN
子句通常比 NOT IN
子句更容易进行优化,因为在 IN
中,数据库可以使用索引来查找匹配的值。而在 NOT IN
中,数据库需要执行逐一比较,以查找在子查询结果中不存在的值。
虽然IN 走了索引优化 , 数据量大的时候,IN 还是可能会很慢
阿里开发规约,也有这样的建议:in 操作能避免则避免,若实在避免不了,需要仔细评估 in 后边的集合元素数量,控 制在 1000 个之内
优化
原始的慢SQL: (子查询存在几十万条数据,主表也是存在几十万条,耗时30min)
SELECT id FROM fine_user_role_middle WHERE userid NOT IN (SELECT id FROM fine_user u WHERE u.creationType = 2);
业务上思考降低 IN 里面的数据数量
SELECT id FROM fine_user_role_middle WHERE userid IN (SELECT id FROM fine_user u WHERE u.creationType = 1 or creationType = 0);
使用 left join
select a.id from fine_user_role_middle a left join fine_user b on a.userId <> b.id where b.creationType = 2;