关于oracle中的in和exists的效率问题

最近做报表的时候发现一段SQL执行速度很慢,如下:selectaa19.分公司as分公司,casewhencount(aa19.独立故障编号)isnullthen0els... 最近做报表的时候发现一段SQL执行速度很慢,如下:
select aa19.分公司 as 分公司,
case when count(aa19.独立故障编号) is null then 0 else count(aa19.独立故障编号) end as 月完成,
sum(aa19.月完成历时) as 月完成总历时
from(
select distinct(b.tr_code) as 独立故障编号,a.applycentcompany as 分公司,(case when b.end_time is null then sysdate else b.end_time end-b.apply_time)*24*60 as 月完成历时
from tr_queryregisterforreport a,tr_register b,tr_return_affirm cc
where b.tr_code = a.tr_code
and cc.cs_code=b.cssystem_no
and b.cssystem_no is not null
and b.reserver1=@prompt('客服工单类型:','A','省公司故障统计分析\客服工单类型',Mono,Free,Persistent,,User:4)
and (case b.status when '4' then '1' when '5' then '1' when '6' then '1' else '0' end ) = '1'
and to_number(to_char(cc.tr_end_time,'yyyymm')) = to_number(substr(to_char(to_date(@prompt('查询日期:','A','故障处理明细表\日期1',Mono,Free,Persistent,,User:2),'yyyymmdd')-1,'yyyymmdd'),1,6))
and to_number(to_char(cc.tr_end_time,'yyyymmdd')) < to_number(@prompt('查询日期:','A','故障处理明细表\日期1',Mono,Free,Persistent,,User:2))
and to_number(to_char(b.apply_time,'yyyymmdd')) = to_number(to_char(cc.tr_end_time,'yyyymmdd'))
--and a.producttype in (select c.name from tr_ywlx c where c.fenlei!='广视通')
and exists(select 1 from tr_ywlx c where c.fenlei!='广视通' and c.name = a.producttype)
)aa19 group by aa19.分公司 having aa19.分公司 like '%分公司%'

最后发现瓶颈在这么一处:
--and a.producttype in (select c.name from tr_ywlx c where c.fenlei!='广视通')
and exists(select 1 from tr_ywlx c where c.fenlei!='广视通' and c.name = a.producttype)
用exists的时候速度要慢很多很多,改用in的话反而会快很多。
(tr_ywlx约有50多条记录,tr_queryregisterforreport约有100W,但相关字段做过normal索引),很迷惘。
希望谁能结合1个简单的实例讲解下in和exists的效率问题,多谢。
主要是能结合一个实例讲解下2者的区别。
展开
 我来答
a5202003
2009-08-12 · TA获得超过2248个赞
知道大有可为答主
回答量:1885
采纳率:75%
帮助的人:585万
展开全部
单说in和exsist,in的效率较差。
原理是什么我也不清楚,用数据库的人都这么说。
百度网友e6ea01f
2009-08-12 · TA获得超过449个赞
知道小有建树答主
回答量:425
采纳率:0%
帮助的人:539万
展开全部
一般来说exists处理起来比in要快很多,优化SQL时一般都是建议将in改为exists,
从你所描述的情况来看:
and a.producttype in (select c.name from tr_ywlx c where c.fenlei!='广视通')---tr_ywlx数据相比之下很小很小,而且这个子查询只是表本身数据的筛选
and exists(select 1 from tr_ywlx c where c.fenlei!='广视通' and c.name = a.producttype)---这里是将tr_ywlx这个数据很小的表与100W笔数据的表关联起来了,形成了一个笛卡尔积,它要将两个表数据一对一进行比对,100W啊,肯定慢了

你给producttype做一个索引再试试
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
dingklw32
2009-08-12 · TA获得超过432个赞
知道小有建树答主
回答量:514
采纳率:0%
帮助的人:316万
展开全部
你的这个SQL实在是太复杂了,而且还用到了外链接,不知道为什么要写的这么复杂,我以前用过exists,比in的效率要高出很多。
关于EXISTS与IN的区别:
EXISTS检查是否有结果,判断是否有记录,返回的是一个布尔型(TRUE/FALSE)。
IN是对结果值进行比较,判断一个字段是否存在于几个值的范围中,所以 EXISTS 比 IN 快。

主要区别是:
exists主要用于片面的,有满足一个条件的即可,
in主要用于具体的集合操作,有多少满足条件.

exists是判断是否存在这样的记录,
in是判断某个字段是否在指定的某个范围内。
exists快一些吧 。

in适合内外表都很大的情况,exists适合外表结果集很小的情况。

参考资料: http://blog.163.com/yangzhongfei/blog/static/4610987520095284185360/

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式