快捷搜索:

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 A

where 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 次。

您可能还会对下面的文章感兴趣: