日期:2014-05-17  浏览次数:20844 次

关于SQL优化中的In和Exists
关于SQL优化中的In和Exists  



SQL语句: 
select b.text from basetable b , extable e  
where b.id=e.id 

select b.text from basetable b where b.id in (select e.id from extable e) 

很多人都说使用in比较快,这是事实,因为笛卡尔积比较小 

有人说使用exist更快: 
select b.text from basetable b where exists (select 'x' from extable e where b.id=e.id) 

经过测试(百万数据),使用exist的确快 
但是,如果将b.text修改为count(b.text),也就是统计条数的话,就没有什么优势了 

我想问两个问题 
1、为什么exists会比in快 

2、为什么使用count来统计的时候会没有优势 

谢谢  
 


------解决方案--------------------
通过使用exist,oracle系统会首先检查主查询,然后运行子查询直到它找到第一个匹配项,这就节省了时间。oracle系统在执行in子查询时,首先执行子查询,并将获得的结果列表存放在在一个加了索引的临时表中。在执行子查询之前,系统先将主查询挂起,待子查询执行完毕,存放在临时表中以后再执行主查询。这也就是使用exists比使用in通常查询速度快的原因
------解决方案--------------------
http://hi.baidu.com/yandavid/blog/item/64fb825000869f638435246d.html
------解决方案--------------------
楼上说法片面,in和exist,各有快的时候,主要是看你的筛选条件是在主查询上还是在子查询上。
下面是oracle文档,:)
In certain circumstances, it is better to use IN rather than EXISTS. In general, if the selective predicate is in the subquery, then use IN. If the selective predicate is in the parent query, then use EXISTS.

Sometimes, Oracle can rewrite a subquery when used with an IN clause to take advantage of selectivity specified in the subquery. This is most beneficial when the most selective filter appears in the subquery and there are indexes on the join columns. Conversely, using EXISTS is beneficial when the most selective filter is in the parent query. This allows the selective predicates in the parent query to be applied before filtering the rows against the EXISTS criteria.


------解决方案--------------------
exists不需要记录,当存在的时候就返回
个人观点,也是以前看到别人回答的
------解决方案--------------------
用exists只检查行的存在性,而in检查到行里的实际的值。