问题背景:
EXISTS 和 IN 运算符用于基于子查询过滤记录。自 SQL 出现以来,开发人员一直在选择它们之间挣扎,试图了解哪种方式更快,以及在什么情况下它们的应用更优先。
问题:
主要任务是只获取在外部或内部表中有对应的行,这对于大数据集的性能始终至关重要。选择 EXISTS 和 IN 取决于子查询的结构、返回值的数量和唯一性,以及使用的数据库管理系统。
解决方案:
代码示例:
-- 使用 IN SELECT name FROM students WHERE id IN (SELECT student_id FROM enrollments WHERE course = 'SQL'); -- 使用 EXISTS SELECT name FROM students WHERE EXISTS (SELECT 1 FROM enrollments WHERE enrollments.student_id = students.id AND enrollments.course = 'SQL');
关键特性:
如果子查询 IN 中遇到 NULL,会发生什么?
许多人认为 IN 只会忽略 NULL,但如果存在 NULL,结果可能是不可预测的。例如,查询:
SELECT id FROM orders WHERE client_id IN (1, NULL, 2);
技术上不会包括 client_id 不等于 1 或 2 的行,但如果子查询中的列表只有 NULL,结果将是空的。
EXISTS 和 IN 是完全可以互换的结构吗?
不是。使用 EXISTS 通常更快,因为不需要分析整个子查询。此外,IN 不适用于返回多个列的子查询,而 EXISTS 可以,因为比较是基于 WHERE 中的条件。例如:
SELECT col1 FROM t1 WHERE (col1, col2) IN (SELECT col3, col4 FROM t2);
这种选项通常不被支持,而类似的 EXISTS 则可以。
在处理索引字段时,IN 可能比 EXISTS 更快吗?
是的,如果子查询较小且比较的字段上有索引,IN 可能会更快。然而在大选择集或没有索引时,情况相反。
分析师使用 IN 方法构建报告,而没有考虑子查询返回数十万行带有 NULL。报告运行了几分钟,有时会丢失数据。
优点:
同样的查询在 EXISTS 上重写,并添加了额外条件,索引进行了重新计算。
优点: