oracle in exists 区别

静思苑 2016-03-27

在OracleSQL中取数据时有时要用到in和exists那么他们有什么区别呢?

1性能上的比较

比如Select*fromT1wherexin(selectyfromT2)

执行的过程相当于:

select*

fromt1,(selectdistinctyfromt2)t2

wheret1.x=t2.y;

相对的

select*fromt1whereexists(selectnullfromt2wherey=x)

执行的过程相当于:

forxin(select*fromt1)

loop

if(exists(selectnullfromt2wherey=x.x)

then

OUTPUTTHERECORD

endif

endloop

表T1不可避免的要被完全扫描一遍

分别适用在什么情况?

以子查询(selectyfromT2)为考虑方向

如果子查询的结果集很大需要消耗很多时间,但是T1比较小执行(selectnullfromt2wherey=x.x)非常快,那么exists就比较适合用在这里

相对应得子查询的结果集比较小的时候就应该使用in.

转载自http://hi.baidu.com/hopedaily/blog/item/56d23edbde87cd60d0164efe.html

in和exists

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

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

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

如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:

例如:表A(小表),表B(大表)

1:

select*fromAwhereccin(selectccfromB)

效率低,用到了A表上cc列的索引;

select*fromAwhereexists(selectccfromBwherecc=A.cc)

效率高,用到了B表上cc列的索引。

相反的

2:

select*fromBwhereccin(selectccfromA)

效率高,用到了B表上cc列的索引;

select*fromBwhereexists(selectccfromAwherecc=B.cc)

效率低,用到了A表上cc列的索引。

in与=的区别

selectnamefromstudentwherenamein('zhang','wang','li','zhao');

selectnamefromstudentwherename='zhang'orname='li'orname='wang'orname='zhao'

的结果是相同的。

in内表全扫,exists外表全扫

in用到外表索引(外表大就快)exists用到子查询索引(子大就快)

notin和notexists

如果查询语句使用了notin那么内外表都进行全表扫描,没有用到索引;

而notextsts的子查询依然能用到表上的索引。

所以无论那个表大,用notexists都比notin要快。

相关推荐