ITPub博客

首页 > 数据库 > Oracle > 在关联子查询中in与exists的区别

在关联子查询中in与exists的区别

原创 Oracle 作者:skyin_1603 时间:2016-10-09 00:08:15 0 删除 编辑
in与exists在子查询中也容易混用,前者表示是否满足,是否在所确定的范围,
后者表示是否存在。理解这两个,还是从null值入手去理解。以下通过一些分解操作
来更深理解这两个的的用法,顺便牵涉一些优化的说法。

背景:
1、在表emp中查看最高领导人员的有关信息:(操作查询前打开sqlplus的计时包:set timing on)

1》Not exists:

SQL> select empno,ename,sal,mgr

  2   from emp  outer

  3  where not exists(

  4  select 0 from emp inner

  5  where outer.mgr = inner.mgr);

     EMPNO ENAME             SAL        MGR

---------- ---------- ---------- ----------

      7839 KING             5000

Elapsed: 00:00:00.01


2》Not in

SQL> select empno,ename,sal,mgr

  2   from emp

  3  where mgr not in(

  4   select mgr from emp);

no rows selected

Elapsed: 00:00:00.00

2、以下将上面的子查询与主查询分解,分别查询结果:
1》主查询:

SQL> select empno,ename,sal,mgr

  2  from emp;

     EMPNO ENAME             SAL        MGR

---------- ---------- ---------- ----------

      7369 SMITH             800       7902

      7499 ALLEN            1600       7698

      7521 WARD             1250       7698

      7566 JONES            2975       7839

      7654 MARTIN           1250       7698

      7698 BLAKE            2850       7839

      7782 CLARK            2450       7839

      7788 SCOTT            3000       7566

      7839 KING             5000             

      7844 TURNER           1500       7698

      7876 ADAMS            1100       7788


     EMPNO ENAME             SAL        MGR

---------- ---------- ---------- ----------

      7900 JAMES             950       7698

      7902 FORD             3000       7566

      7934 MILLER           1300       7782

14 rows selected. 



2》子查询:

SQL>  select mgr from emp;

       MGR

----------

      7902

      7698

      7698

      7839

      7698

      7839

      7839

      7566


      7698

      7788


       MGR

----------

      7698

      7566

      7782

14 rows selected.

发现,子查询存在为空值null的行。

3》正面查询:

SQL> select empno,ename,sal,mgr

  2  from emp

  3  where mgr in(

  4  select mgr from emp);

     EMPNO ENAME             SAL        MGR

---------- ---------- ---------- ----------

      7369 SMITH             800       7902

      7900 JAMES             950       7698

      7844 TURNER           1500       7698

      7654 MARTIN           1250       7698

      7521 WARD             1250       7698

      7499 ALLEN            1600       7698

      7782 CLARK            2450       7839

      7698 BLAKE            2850       7839

      7566 JONES            2975       7839

      7902 FORD             3000       7566

      7788 SCOTT            3000       7566


     EMPNO ENAME             SAL        MGR

---------- ---------- ---------- ----------

      7876 ADAMS            1100       7788

      7934 MILLER           1300       7782

13 rows selected.

可以看到,in查询,只有13行,比上面的14行少了一行,因为 null <> null。

3、比较两者查询的时间花费:
查看入职时间为80年员工的信息:

1》Exists耗时:

SQL> select empno,ename,sal,hiredate

  2  from emp outer

  3  where exists(

  4  select 1 from emp inner

  5  where outer.empno = inner.empno

  6  and substr(hiredate,8,2) ='80');

     EMPNO ENAME             SAL HIREDATE

---------- ---------- ---------- ---------

      7369 SMITH             800 17-DEC-80

Elapsed: 00:00:00.01


2》In耗时:

SQL> select empno,ename,sal,hiredate

  2  from emp outer

  3  where 1 in(

  4  select 1 from emp inner

  5   where outer.empno = inner.empno

  6  and substr(hiredate,8,2) ='80');


     EMPNO ENAME             SAL HIREDATE

---------- ---------- ---------- ---------

      7369 SMITH             800 17-DEC-80

Elapsed: 00:00:00.05


通过上面的两个方面的测试看出,一个两者在关联子查询时候所表示的条件范围不一样,
in表示外部的结果与内部查询结果匹配,exists表示外部的结果是否存在于内部的查询结果。
再有,在查询相同任务的时候,exists耗时大大小于in的耗时。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31392094/viewspace-2125963/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2016-09-06

  • 博文量
    231
  • 访问量
    215114