oracle中exist与in的区别

在Oracle SQL中取数据时有时要用到in 和exists 那么他们有什么区别呢?
1 性能上的比较
比如Select * from T1 where x in ( select y from T2 )
执行的过程相当于:
select *
from t1, ( select distinct y from t2 ) t2
where t1.x = t2.y;
相对的
select * from t1 where exists ( select null from t2 where y = x )
执行的过程相当于:
for x in ( select * from t1 )
loop
if ( exists ( select null from t2 where y = x.x )
then
OUTPUT THE RECORD
end if
end loop
表 T1 不可避免的要被完全扫描一遍
分别适用在什么情况?
以子查询 ( select y from T2 )为考虑方向
如果子查询的结果集很大需要消耗很多时间,但是T1比较小执行( select null from t2 where y = x.x )非常快,那么exists就比较适合用在这里
相对应得子查询的结果集比较小的时候就应该使用in.
2 含义上的比较
在标准的scott/tiger用户下
执行
SQL> select count(*) from emp where empno not in ( select mgr from emp );
COUNT(*)
----------
SQL> select count(*) from emp T1
2 where not exists ( select null from emp T2 where t2.mgr = t1.empno ); -- 这里子查询中取出null并没有什么特殊作用,只是表示取什么都一样。

COUNT(*)
----------
8
结果明显不同,问题就出在MGR=null的那条数据上。

任何值X not in (null) 结果都不成立。

用一个小例子试验一下:
select * from dual where dummy not in ( NULL ) -- no rows selected
select * from dual where NOT( dummy not in ( NULL ) ) --no rows selected
知觉上这两句SQL总有一句会取出数据的,但是实际上都没有。

SQL 中逻辑表达式的值可以有三种结果(true false null)而null相当于false.。

合集下载

ORACLE中IN和EXISTS的区别

ORACLE中IN和EXISTS的区别

ORACL‎E中IN‎和EXIS‎T S的区别‎EX‎I STS的‎执行流程‎‎s elec‎t * f‎r om t‎1 whe‎r e ex‎i sts ‎( sel‎e ct n‎u ll f‎r om t‎2 whe‎r e y ‎= x )‎可以理解‎为:‎f or x‎in (‎sele‎c t * ‎f rom ‎t1 )‎ loo‎p‎ if‎( ex‎i sts ‎( sel‎e ct n‎u ll f‎r om t‎2 whe‎r e y ‎= x.x‎)‎ t‎h en‎‎ OUT‎P UT T‎H E RE‎C ORD‎‎end ‎i f‎e nd l‎o op对‎于in 和‎exis‎t s的性能‎区别:‎如果子查‎询得出的结‎果集记录较‎少,主查询‎中的表较大‎且又有索引‎时应该用i‎n,反之如‎果外层的主‎查询记录较‎少,子查询‎中的表大,‎又有索引时‎使用exi‎s ts。

‎其实我‎们区分in‎和exis‎t s主要是‎造成了驱动‎顺序的改变‎(这是性能‎变化的关键‎),如果是‎e xist‎s,那么以‎外层表为驱‎动表,先被‎访问,如果‎是IN,那‎么先执行子‎查询,所以‎我们会以驱‎动表的快速‎返回为目标‎,那么就会‎考虑到索引‎及结果集的‎关系了‎‎‎‎‎‎另外IN时‎不对NUL‎L进行处理‎如:s‎e lect‎1 fr‎o m du‎a l wh‎e re n‎u ll ‎i n (0‎,1,2,‎n ull)‎为空‎2.NOT‎IN 与‎N OT E‎X ISTS‎:‎NOT‎EXIS‎T S的执行‎流程se‎l ect ‎.....‎fr‎o m ro‎l lup ‎Rwhe‎r e no‎t exi‎s ts (‎sele‎c t 'F‎o und'‎from‎titl‎e T‎‎‎‎‎‎ whe‎r e R.‎s ourc‎e_id ‎= T.T‎i tle_‎I D);‎可以理解为‎:for‎x in‎( se‎l ect ‎* fro‎m rol‎l up )‎‎ loo‎p‎‎ if ‎( not‎exis‎t s ( ‎t hat ‎q uery‎) ) ‎t hen‎‎‎‎OUTP‎U T‎‎ en‎d if;‎‎ end‎;注意‎:NOT ‎E XIST‎S与 N‎O T IN‎不能完全‎互相替换,‎看具体的需‎求。

OracleIn和existsnotin和notexists的比较分析

OracleIn和existsnotin和notexists的比较分析

OracleIn和existsnotin和notexists的⽐较分析
把这两个很普遍性的⽹友⽐较关⼼的问题总结回答⼀下。

in和exist的区别
从sql编程⾓度来说,in直观,exists不直观多⼀个select,
in可以⽤于各种⼦查询,⽽exists好像只⽤于关联⼦查询
从性能上来看
exists是⽤loop的⽅式,循环的次数影响⼤,外表要记录数少,内表就⽆所谓了
in⽤的是hash join,所以内表如果⼩,整个查询的范围都会很⼩,如果内表很⼤,外表如果也很⼤就很慢了,这时候exists才真正的会快过in的⽅式。

not in和not exists的区别
not in内外表都进⾏全表扫描,没有⽤到索引;
not extsts 的⼦查询能⽤到表上的索引。

所以推荐⽤not exists代替not in
不过如果是exists和in就要具体看情况了
有时间⽤具体的实例和执⾏计划来说明。

Oracle中in和exists的区别

Oracle中in和exists的区别

in和exists的区别“exists”和“in”是Oracle中,都是查询某集合的值是否存在在另一个集合,但对不同的数据有不同的用法,主要是在效率问题上存在很大的差别,以下有两个简单例子,以说明“exists”和“in”的效率问题。

1、select * from Table1 where exists(select 1 from Table2 where Table1.a=Table2.a) ; Table1数据量小而Table2数据量非常大时,Table1<<Table2 时,1、的查询效率高。

2、select * from Table1 where Table1.a in (select Table2.a from Table2) ;Table1数据量非常大而Table2数据量小时,Table1>>Table2 时,2、的查询效率高。

详细解释下“exists”和“in”的用法exists 用法:请注意1、,理解其含义;其中“select 1 from Table2 where Table1.a=Table2.a”相当于一个关联表查询,相当于“select 1 from Table1,Table2 where Table1.a=Table2.a”但是,如果你单单执行1、句括号里的语句,是会报语法错误的,这也是使用exists需要注意的地方。

“exists(xxx)”就表示括号里的语句能不能查出记录,它要查的记录是否存在。

因此“select 1”这里的“1”其实是无关紧要的,换成“*”也没问题,它只在乎括号里的数据能不能查找出来,是否存在这样的记录,如果存在,这1、句的where 条件成立。

in 的用法:继续引用上面的例子“2、select * from Table1 where Table1.a in (select Table2.a from Table2) ”这里的“in”后面括号里的语句搜索出来的字段的内容一定要相对应,一般来说,Table1和Table2这两个表的a字段表达的意义应该是一样的,否则这样查没什么意义。

oracle中exist的用法

oracle中exist的用法

oracle中exist的用法在Oracle数据库中,EXISTS是一种用于检查子查询结果是否为空的关键字。

它可以用于WHERE子句或HAVING子句中,以便在查询中过滤掉不需要的数据。

在本文中,我们将深入探讨Oracle中EXISTS的用法,包括语法、示例和最佳实践。

语法EXISTS的语法如下:SELECT column1, column2, ...FROM table_nameWHERE EXISTS (SELECT column_name FROM table_name WHERE condition);其中,column1、column2等是要查询的列名,table_name是要查询的表名,condition是子查询中的条件。

如果子查询返回结果,则WHERE子句中的条件将被视为TRUE,否则将被视为FALSE。

示例让我们看一些使用EXISTS的示例。

1. 检查子查询结果是否为空假设我们有一个名为employees的表,其中包含员工的姓名和工资。

我们想要找到工资高于平均工资的员工。

我们可以使用以下查询:SELECT name, salaryFROM employees e1WHERE salary > (SELECT AVG(salary) FROM employees e2);但是,如果我们只想找到工资高于平均工资的员工中的前5个,我们可以使用EXISTS来实现:SELECT name, salaryFROM employees e1WHERE EXISTS (SELECT 1 FROM employees e2 WHERE e2.salary > (SELECT AVG(salary) FROM employees) AND e2.salary > e1.salary)AND ROWNUM <= 5;在这个查询中,我们使用了EXISTS来检查子查询的结果是否为空。

oracle exist 用法

oracle exist 用法

oracle exist 用法Oracle中的EXISTS函数是一种用于判断子查询是否返回结果的函数。

它返回一个布尔值,即TRUE或FALSE。

在这篇文章中,我们将详细介绍Oracle的EXISTS函数的用法以及如何正确使用它。

一、什么是Oracle的EXISTS函数在Oracle数据库中,EXISTS函数被用来判断一个子查询是否返回结果。

它的语法如下:SELECT column_name(s)FROM table_nameWHERE EXISTS (subquery);其中,column_name(s)是要选择的列名,table_name是要查询的表名,subquery是一个子查询。

二、EXISTS函数的用法1. 判断子查询是否返回结果EXISTS函数用于判断一个子查询是否返回结果。

如果子查询返回了至少一行数据,EXISTS函数会返回TRUE;如果子查询没有返回任何数据,EXISTS函数会返回FALSE。

这种判断适用于在查询时需要根据子查询的结果进行条件过滤的场景。

下面是一个例子,我们通过使用EXISTS函数来查询有员工的部门:SELECT department_nameFROM departmentsWHERE EXISTS (SELECT 1FROM employeesWHERE employees.department_id = departments.department_id);在上面的例子中,我们通过子查询判断在employees表中是否存在与departments表中的department_id相等的数据。

如果存在,就会返回部门的名称。

2. 使用EXISTS函数进行相关子查询除了判断子查询是否返回结果外,EXISTS函数还可以与其他列进行关联查询。

例如,在查询时,我们可以使用EXISTS函数来查找与特定条件相关联的记录。

下面是一个例子,我们通过使用EXISTS函数来查询具有高薪水的员工所在的部门:SELECT department_nameFROM departmentsWHERE EXISTS (SELECT 1FROM employeesWHERE employees.department_id = departments.department_idAND employees.salary > 5000);在上面的例子中,我们通过子查询判断是否有员工薪水高于5000,如果存在,就返回员工所在的部门名称。

Oracle中in与exist,not in与not exist的性能问题

Oracle中in与exist,not in与not exist的性能问题

上星期五与haier讨论in跟exists的性能问题,正好想起原来公司的一个关于not in的规定,本想做个实验证明我的观点是正确的,但多次实验结果却给了我一个比较大的教训。

我又咨询了下oracle公司工作的朋友,确实是我持有的观点太保守了。

于是写个文章总结下,希望对大家有所启发。

后面可能有大篇是关于10053 trace的内容,只作实验证明,可直接忽略看最终的结论即可。

我们知道,in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。

一直以来认为exists比in效率高的说法是不准确的。

如果查询的两个表大小相当,那么用in和exists是差别不大的。

但如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in,效率才是最高的。

假定表A(小表),表B(大表),cc列上都有索引:•select * from A where cc in(select ccfrom B); --效率低,用到了A表上cc列的索引•select * from A where exists(select cc from B where cc=A.cc); --效率高,用到了B 表上cc列的索引。

相反的:•select * from B where cc in (select cc from A); --效率高,用到了B表上cc列的索引•select * from B where exists(select ccfromA where cc=); --效率低,用到了A表上cc列的索引通过使用exists,Oracle会首先检查主查询,然后运行子查询直到它找到第一个匹配项,这就节省了时间。

Oracle在执行IN子查询时,首先执行子查询,并将获得的结果列表存放在一个加了索引的临时表中。

在执行子查询之前,系统先将主查询挂起,待子查询执行完毕,存放在临时表中以后再执行主查询。

oracle中的exists和in用法详解

oracle中的exists和in⽤法详解以前⼀直不知道exists和in的⽤法与效率,这次的项⽬中需要⽤到,所以⾃⼰研究了⼀下。

下⾯是我举两个例⼦说明两者之间的效率问题。

前⾔概述:“exists”和“in”的效率问题,涉及到效率问题也就是sql优化:1.若⼦查询结果集⽐较⼩,优先使⽤in。

2.若外层查询⽐⼦查询⼩,优先使⽤exists。

原理是:若匹配到结果,则退出内部查询并将条件标志为true,传回全部结果资料因为若⽤in,则oracle会优先查询⼦查询,然后匹配外层查询,原理是:in不管匹配到匹配不到都全部匹配完毕,匹配相等就返回true,就会输出⼀条元素.若使⽤exists,则oracle会优先查询外层表,然后再与内层表匹配也就是:”匹配原则,拿最⼩记录匹配⼤记录。

也就是遍历的次数越少越好"例⼦如下:1) select * from T_USER1 where exists(select 1 from T_USER2 where T_USER1.jxb_id =T_USER2.jxb_id ) ;T_USER1 数据量⼩⽽T_USER2 数据量⾮常⼤时,T_USER1 <<T_USER2 时,1) 的查询效率⾼。

原理解析:以上查询使⽤了exists语句,sql语句如:select a.* from A a where exists(select 1 from B b where =)exists()会执⾏A.length次,它并不缓存exists()结果集,因为exists()结果集的内容并不重要,重要的是结果集中是否有记录,如果有则返回true,没有则返回false.它的查询过程类似于以下过程:1 List resultSet=[];2 Array A=(select * from A)34for(int i=0;i<A.length;i++) { //这个循环次数越少越好5if(exists(A[i].id) { //执⾏select 1 from B b where b.id=a.id是否有记录返回6 resultSet.add(A[i]);7 }8 }9return resultSet;当B表⽐A表数据⼤时适合使⽤exists(),因为它没有那么遍历操作,只需要再执⾏⼀次查询就⾏.如:A表有10000条记录,B表有1000000条记录,那么exists()会执⾏10000次去判断A表中的id是否与B表中的id相等.如:A表有10000条记录,B表有100000000条记录,那么exists()还是执⾏10000次,因为它只执⾏A.length次,可见B表数据越多,越适合exists()发挥效果再如:A表有10000条记录,B表有100条记录,那么exists()还是执⾏10000次,还不如使⽤in()遍历10000*100次,因为in()是在内存⾥遍历⽐较,⽽exists()需要查询数据库,我们都知道查询数据库所消耗的性能更⾼,⽽内存⽐较很快.2) select * from T_USER1 where T_USER1.jxb_id in (select T_USER2 .jxb_id from T_USER2 ) ;T_USER1 数据量⾮常⼤⽽T_USER2数据量⼩时,T_USER1 >>T_USER2时,2) 的查询效率⾼。

in和extexs

in和exists的区别与SQL执行效率in和exists的区别与SQL执行效率最近很多论坛又开始讨论in和exists的区别与SQL执行效率的问题,本文特整理一些in和exists的区别与SQL执行效率分析SQL中in可以分为三类:1、形如select * from t1 where f1 in ('a','b'),应该和以下两种比较效率select * from t1 where f1='a' or f1='b'或者select * from t1 where f1 ='a' union all select * from t1 f1='b'你可能指的不是这一类,这里不做讨论。

2、形如select * from t1 where f1 in (select f1 from t2 where t2.fx='x'),其中子查询的where里的条件不受外层查询的影响,这类查询一般情况下,自动优化会转成exist语句,也就是效率和exist一样。

3、形如select * from t1 where f1 in (select f1 from t2 where t2.fx=t1.fx),其中子查询的where里的条件受外层查询的影响,这类查询的效率要看相关条件涉及的字段的索引情况和数据量多少,一般认为效率不如exists。

除了第一类in语句都是可以转化成exists 语句的SQL,一般编程习惯应该是用exi sts而不用in,而很少去考虑in和exists的执行效率.in和exists的SQL执行效率分析A,B两个表,(1)当只显示一个表的数据如A,关系条件只一个如ID时,使用IN更快:select * from A where id in (select id from B)(2)当只显示一个表的数据如A,关系条件不只一个如ID,col1时,使用IN就不方便了,可以使用EXISTS:select * from Awhere exists (select 1 from B where id = A.id and col1 = A.col1)(3)当只显示两个表的数据时,使用IN,EXISTS都不合适,要使用连接:select * from A left join B on id = A.id所以使用何种方式,要根据要求来定。

oracle in 的用法

EXISTS的执行流程select * from t1 where exists ( select null from t2 where y = x )可以理解为:for x in ( select * from t1 )loopif ( exists ( select null from t2 where y = x.x )thenOUTPUT THE RECORDend ifend loop对于in 和exists的性能区别:如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用in,反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用exists。

其实我们区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询,所以我们会以驱动表的快速返回为目标,那么就会考虑到索引及结果集的关系了另外IN时不对NULL进行处理如:select 1 from dual where null in (0,1,2,null)为空2.NOT IN 与NOT EXISTS:NOT EXISTS的执行流程select .....from rollup Rwhere not exists ( select 'Found' from title Twhere R.source_id = T.Title_ID);可以理解为:for x in ( select * from rollup )loopif ( not exists ( that query ) ) thenOUTPUTend if;end;注意:NOT EXISTS 与NOT IN 不能完全互相替换,看具体的需求。

如果选择的列可以为空,则不能被替换。

例如下面语句,看他们的区别:select x,y from t;x y------ ------1 33 11 21 13 15select * from t where x not in (select y from t t2 )no rowsselect * from t where not exists (select null from t t2where t2.y=t.x )x y------ ------5 NULL所以要具体需求来决定对于not in 和not exists的性能区别:not in 只有当子查询中,select 关键字后的字段有not null约束或者有这种暗示时用not in,另外如果主查询中表大,子查询中的表小但是记录多,则应当使用not in,并使用anti hash join.如果主查询表中记录少,子查询表中记录多,并有索引,可以使用not exists,另外not in 最好也可以用/*+ HASH_AJ */或者外连接+is nullNOT IN 在基于成本的应用中较好比如:select .....from rollup Rwhere not exists ( select 'Found' from title Twhere R.source_id = T.Title_ID);改成(佳)select ......from title T, rollup Rwhere R.source_id = T.Title_id(+)and T.Title_id is null;或者(佳)sql> select /*+ HASH_AJ */ ...from rollup Rwhere ource_id NOT IN ( select ource_idfrom title Twhere ource_id IS NOT NULL )注意:上面只是从理论上提出了一些建议,最好的原则是大家在上面的基础上,能够使用执行计划来分析,得出最佳的语句的写法希望大家提出异议。

oracle中in与exist_not_in与not_exist_的区别

sql语句中in与exist not in与not exist 的区别Oracle 中in和existsin 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。

一直以来认为exists比in效率高的说法是不准确的。

如果查询的两个表大小相当,那么用in和exists差别不大。

如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:例如:表A(小表),表B(大表)1:select * from A where cc in (select cc from B)效率低,用到了A表上cc列的索引;select * from A where exists(select cc from B where cc=)效率高,用到了B表上cc列的索引。

相反的2:select * from B where cc in (select cc from A)效率高,用到了B表上cc列的索引;select * from B where exists(select cc from A where cc=)效率低,用到了A表上cc列的索引。

not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。

所以无论那个表大,用not exists都比not in要快。

in 与=的区别select name from student where name in ('zhang','wang','li','zhao');与select name from student where name='zhang' or name='li' or name='wang' or name='zhao'的结果是相同的。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档