赞
踩
今天看SQL语句的时候发现了exists这个关键字,记得刚用这个关键字的时候只知道它和关键字IN的作用是一样的,当时觉得无非就是我的条件匹配到子结果集里面的数据。今天打算把这两个关键字具体怎么回事区分一下,上网上看了一下,懂了一些两者的区别,其中还涉及到了性能问题,很吃惊!
2018-11-8再次更新:
问题说明:在略懂了in 和 exists的区别之后,自认为子查询结果集的数据少的情况下可以用 NOT IN,但是忽略了一个至关重要的问题,我要进行的子查询的结果集很多,
特别说明:oracle中not in的数据参数,不可以超过1000个,否则会报SQL执行出错。所以说,同志们,还是用exists吧,血和泪的教训啊。
同时也知道了一些关于Null在子查询IN和Not IN的区别。
开发时候谨记:
所以当我们要去进行某一个字段的不等于过滤查询时,我们要搞清楚,我们的查询是否要包含NULL值。
这里先说下EXISTS这个关键字,exists返回的是一个布尔值,oracle根据true或者false进行判断,如果为true,将结果保留进行,如果为false,则不保留。
EXISTS会先去进行主查询,也就是exists之前的部分,如:
select t.name,t.sex from A t where t.dr = 0 and exists (select B.id from B where B.pk = B.pk);
PS:exists中的查询语句一定要和前面的表进行关联,达到过滤的目的
进行完主查询之后得到一个结果集,再对结果集的每一行去对exits后面的语句进行匹配,为真则保留,为false则不保留,最后返回查询的结果集。
注意:exists前面是不能加类似于字段名的,否则会报无效关系运算的错误,如图:
2018-10-19 再次强调一个东西,就是exists 中SQL语句的书写
像上面这种写法,达不到进行过滤的条件,exists中必须加上和外表进行的关联的条件,否则无法达到过滤,正确写法应该是下面这样的写法
可能是对于exits的用法还不够透彻!
IN关键字则是先去进行子查询,也就是IN之后的部分,如:
select t.name,t.sex from A t where t.dr = 0 and m.id in (select * from B m where m.pk = t.pk);
进行完子查询之后会得到一个结果集,和主表做笛卡尔积,然根据过滤条件得到最后的结果集。
到这里,可以知道,如果主查询要查的东西多,用exists,如果子表要查的东西多,用in。
特别说明:
IN关键字在进行排序的时候使用的是hash join算法 连接表与表,
EXISTS关键字在进行排序的时候使用的是loop算法连接表与表。
这两种算法具体怎么回事还不清楚.............
这里介绍几个数据库里的名词:
在plsql中按F5会进行SQL语句的执行计划。以下几个名词可能会看到,截图如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。