exists 和 in 的区别

来源:互联网 发布:芜湖神淘宝店网址 编辑:程序博客网 时间:2024/05/18 01:55

网友1:

复习一下in&exist语法:
一般来讲in是对外表和内表作Hash Join,而exist是对外表和内表做了一个nested loop,也就是说,对于exist,针对外表(需要遍历其所有内容)需要遍历的每一行,都会对内表进行一次查询,因此如果外表和内表大小相当,in和exist在性能的差别上就不是很大:)
如果两个表中一个是较小的表,一个是较大的表,如果内表大则用exists性能会更好(因为外表小了,遍历的行次数就少了很多),内表表小的用in性能会更好。

举个例子:
例如:表A(小表),表B(大表),CC列上有索引
在外表小,内表大的情况下用in(Hash Join A和B两个表).效率就会很低,比如:
select * from A where cc in (select cc from B)
这个时候查询用到了A表上cc列的索引,但是因为A是小表,而且大表B上的索引也没有充分利用,因此效率不高

而如果用了exist,我们发现走的是对A,B两个表的nested Loop,对于遍历A的每一行,都会对大表B进行一次查询(可能对B表的查询结果不是太多.)
select * from A where exists(select cc from B where cc=A.cc)
这样效率会高些,因为用到了B表(大表)上cc列的索引。
 
 not in 和not exists
如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;
而not extsts 的子查询依然能用到表上的索引。
所以无论那个表大,用not exists都比not in要快。

 

 

 

 网友2:

执行顺序不同,in和not in是先执行in和not in条件里的语句,然后执行主查询,exists和not exists是先执行主语句然后执行exists和not exists条件里的语句。
效率上来说exists比in要好,尽量少用in和not in。在大容量数据里是绝对不能使用not in来查询的,很容易死机,我原来的在数据量极大的情况下使用过not in结果给服务器带来了很大的负载。

 

 

 

网友3:

1.用EXISTS替代IN
在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接.在这种情况下, 使用EXISTS(或NOT EXISTS)通常将提高查询的效率.

低效:
SELECT *
FROM EMP (基础表)
WHERE EMPNO > 0
AND DEPTNO IN (SELECT DEPTNO
FROM DEPT
WHERE LOC = ‘MELB’)
   
高效:
SELECT *
FROM EMP (基础表)
WHERE EMPNO > 0
AND EXISTS (SELECT ‘X’
FROM DEPT
WHERE DEPT.DEPTNO = EMP.DEPTNO
AND LOC = ‘MELB’)
  (相对来说,用NOT EXISTS替换NOT IN 将更显著地提高效率)
 
2. 用NOT EXISTS替代NOT IN
在子查询中,NOT IN子句将执行一个内部的排序和合并. 无论在哪种情况下,NOT IN都是最低效的 (因为它对子查询中的表执行了一个全表遍历).  为了避免使用NOT IN ,我们可以把它改写成外连接(Outer Joins)或NOT EXISTS.
例如:
SELECT …
FROM EMP
WHERE DEPT_NO NOT IN (SELECT DEPT_NO
                        FROM DEPT
                        WHERE DEPT_CAT=’A’);

为了提高效率.改写为:

(方法一: 高效)
SELECT ….
FROM EMP A,DEPT B
WHERE A.DEPT_NO = B.DEPT(+)
AND B.DEPT_NO IS NULL
AND B.DEPT_CAT(+) = ‘A’


(方法二: 最高效)
SELECT ….
FROM EMP E
WHERE NOT EXISTS (SELECT ‘X’
                    FROM DEPT D
                    WHERE D.DEPT_NO = E.DEPT_NO
                    AND DEPT_CAT = ‘A’);

本人在使用中发现左外连接性能比not exist更高效,请大家进一步验证。
3.用表连接替换EXISTS
      通常来说 , 采用表连接的方式比EXISTS更有效率
      SELECT ENAME
      FROM EMP E
      WHERE EXISTS (SELECT ‘X’
                      FROM DEPT
                      WHERE DEPT_NO = E.DEPT_NO
                      AND DEPT_CAT = ‘A’);

    (更高效)
      SELECT ENAME
      FROM DEPT D,EMP E
      WHERE E.DEPT_NO = D.DEPT_NO
      AND DEPT_CAT = ‘A’ ;
(在RBO的情况下,前者的执行路径包括FILTER,后者使用NESTED LOOP)

4.用EXISTS替换DISTINCT
当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT. 一般可以考虑用EXIST替换
例如:
低效:
    SELECT DISTINCT DEPT_NO,DEPT_NAME
    FROM DEPT D,EMP E
    WHERE D.DEPT_NO = E.DEPT_NO
高效:
    SELECT DEPT_NO,DEPT_NAME
    FROM DEPT D
    WHERE EXISTS ( SELECT ‘X’
                    FROM EMP E
                    WHERE E.DEPT_NO = D.DEPT_NO);
  EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果.

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 宝宝3岁还不会说话 怎么办 两岁宝宝流口水厉害怎么办 两周宝宝不说话怎么办 两岁宝宝说话有点口吃怎么办 一周岁的宝宝脾气不好怎么办 九个月的宝宝脾气不好怎么办 两岁宝宝脾气不好怎么办 2岁宝宝脾气不好怎么办 3岁宝宝脾气不好怎么办 脾气不好吓到宝宝了怎么办 四个月宝宝脾气不好怎么办 5岁说话不清楚该怎么办 小孩快上幼儿园了不怎么说话怎么办 四岁宝宝吐字不清楚怎么办 孕28周胎儿腿短怎么办 b超显示腿短怎么办 2岁多宝宝不愿意说话怎么办 6岁儿童咬字不清怎么办 两岁宝宝爱看电视怎么办 两岁宝宝喜欢看电视怎么办 三岁宝宝说话不清晰怎么办 儿子快四岁了说话不清楚怎么办 儿子快三岁了说话不清楚怎么办 2岁宝宝受刺激了怎么办 一岁的宝宝口臭怎么办 古话说小孩牙齿掉了怎么办 宝宝三岁胆子小怎么办 小宝宝就是不愿意学说话怎么办 2岁宝宝体重偏重怎么办 三岁宝宝体重偏重怎么办 3岁宝宝说话晚怎么办 孩子吃饭总说话吃饭慢怎么办 我的孩子不聪明怎么办 小孩个子长不高怎么办 晚修自己老喜欢讲话怎么办 宝2岁宝脾气大怎么办 宝宝比同龄孩子发育晚怎么办 早教机构业绩不好怎么办 孩子上早教课哭怎么办 两岁宝宝哭闹不止怎么办 7个月宝宝怕生疏怎么办