Oracle 里面只要该技术还依然存在,就说明它一定有应用场景,否则就直接淘汰了。
正确的做法是:比较两者的执行计划。
如果非要给一个建议,如下是一般性建议:
(1). 如果限制性强的条件在子查询,则用 in。
(2). 如果限制性强的条件在主查询,则用 exist。
例1:查询 sales 部门的所有员工信息
使用 in 语句为:
select e.*
from emp e
where e.deptno in
(select d.deptno from dept d where d.dname='SALES');
等价的 exists 语句为:
select e.*
from emp e
where exists (
select 1 from dept d where e.deptno = d.deptno and d.dname='SALES');
在 IN 语句中,先按 dname 字段上的索引访问 dept 表,再 emp 表的 deptno 字段上的索引访问 emp 表。
在 EXISTS 语句中,先进行 EMP 表的全表扫描,再到 DEPT 表中查询过滤。
在一位 ACS 写的书中,以执行计划截图证明了上面的说法,此时, exists 效率低于 in。
例2:查询员工编号为 7499,并且部门位于 DALLAS 的详细员工信息
使用 exists 语句为:
select e.*
from emp e
where empno = 7499
and exists (
select 1 from dept d
where e.deptno = d.deptno
and d.loc='DALLAS');
使用 in 语句为:
select e.*
from emp e
where empno = 7499
and deptno in (
select deptno from dept d where d.loc='DALLAS');
这里假设 DALLAS 包括多个部门,DEPT 表的 loc 字段的可选性显然低于 EMP 表基于 empno 的主键。在 ACS 写的书中,以执行计划截图证明了上面的说法,此时, exists 效率高于 in。
然而,这两个例子,我们在 11g R2 和 19c 均做过测试,无论是 HR 用户还是 SCOTT 用户下的表,每个例子两种方式的执行计划都一样或者差不多。
所以, exists 好还是 in 好,我们最终还是要看执行计划。