SQL语句中 in和exist区别

 我来答
匿名用户
推荐于2017-11-28
展开全部
本文主要分析了in和exists的区别与执行效率的问题:
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 语句的,一般编程习惯应该是用exists而不用in.

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

所以使用何种方式,要根据要求来定。

这是一般情况下做的测试:

测试结果:

set statistics io on select * from sysobjects where exists (select 1 from syscolumns where id=syscolumns.id) select * from sysobjects where id in (select id from syscolumns ) set statistics io off (47 行受影响)

表 'syscolpars '。扫描计数 1,逻辑读取 3 次,物理读取 0 次,预读 2 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

表 'sysschobjs '。扫描计数 1,逻辑读取 3 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

(1 行受影响)

(44 行受影响)

表 'syscolpars '。扫描计数 47,逻辑读取 97 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

表 'sysschobjs '。扫描计数 1,逻辑读取 3 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

(1 行受影响)

set statistics io on select * from syscolumns where exists (select 1 from sysobjects where id=syscolumns.id) select * from syscolumns where id in (select id from sysobjects ) set statistics io off
(419 行受影响)

表 'syscolpars '。扫描计数 1,逻辑读取 10 次,物理读取 0 次,预读 15 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

表 'sysschobjs '。扫描计数 1,逻辑读取 3 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

(1 行受影响)

(419 行受影响)

表 'syscolpars '。扫描计数 1,逻辑读取 10 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

表 'sysschobjs '。扫描计数 1,逻辑读取 3 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

(1 行受影响)

测试结果(总体来讲exists比in的效率高):

效率:条件因素的索引是非常关键的

把syscolumns 作为条件:syscolumns 数据大于sysobjects

用in

扫描计数 47,逻辑读取 97 次,

用exists

扫描计数 1,逻辑读取 3 次

把sysobjects作为条件:sysobjects的数据少于syscolumns

exists比in多预读 15 次
匿名用户
2013-08-17
展开全部
in 和 exists也是很好区别的.

in 是一个集合运算符.

a in {a,c,d,s,d....}

这个运算中,前面是一个元素,后面是一个集合,集合中的元素类型是和前面的元素一样的.

而exists是一个存在判断,如果后面的查询中有结果,则exists为真,否则为假.

in 运算用在语句中,它后面带的select 一定是选一个字段,而不是select *.

比如说你要判断某班是否存在一个名为"小明"的学生,你可以用in 运算:

"小明" in (select sname from student)

这样(select sname from student) 返回的是一个全班姓名的集合,in用于判断"小明"是否为此集合中的一个数据;

同时,你也可以用exists语句:

exists (select * from student where sname="小明")
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
匿名用户
2013-08-17
展开全部
IN
确定给定的值是否与子查询或列表中的值相匹配。 EXISTS
指定一个子查询,检测行的存在。 比较使用 EXISTS 和 IN 的查询这个例子比较了两个语义类似的查询。第一个查询使用 EXISTS 而第二个查询使用 IN。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
匿名用户
2013-08-17
展开全部
一些带EXISTS或NOT EXISTS谓词的子查询不能被其他形式的子查询等价替换,但所有带IN谓词、比较运算符、ANY和ALL谓词的子查询都能用带EXISTS谓词的子查询等价替换

一般SQL语句中EXISTS用得比较少
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

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

类别

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

说明

0/200

提交
取消

辅 助

模 式