in和exists的区别与执行效率问题解析

文章作者 100test 发表时间 2008:04:02 14:23:53
来源 100Test.Com百考试题网


in可以分为三类:

  1、形如0select * from t1 where f1 in ( &.apos;a &.apos;, &.apos;b &.apos;),应该和以下两种比较效率

  0select * from t1 where f1= &.apos;a &.apos; or f1= &.apos;b &.apos;

  或者 0select * from t1 where f1 = &.apos;a &.apos; union all 0select * from t1 f1= &.apos;b &.apos;

  你可能指的不是这一类,这里不做讨论。

  2、形如0select * from t1 where f1 in (0select f1 from t2 where t2.fx= &.apos;x &.apos;),

  其中子查询的where里的条件不受外层查询的影响,这类查询一般情况下,自动优化会转成exist语句,也就是效率和exist一样。

  3、形如0select * from t1 where f1 in (0select f1 from t2 where t2.fx=t1.fx),

  其中子查询的where里的条件受外层查询的影响,这类查询的效率要看相关条件涉及的字段的索引情况和数据量多少,一般认为效率不如exists.

  除了第一类in语句都是可以转化成exists 语句的,一般编程习惯应该是用exists而不用in.

  A,B两个表,

  (1)当只显示一个表的数据如A,关系条件只一个如ID时,使用IN更快:

  0select * from A where id in (0select id from B)

  (2)当只显示一个表的数据如A,关系条件不只一个如ID,col1时,使用IN就不方便了,可以使用EXISTS:

  0select * from A

  where exists (0select 1 from B where id = A.id and col1 = A.col1)

  (3)当只显示两个表的数据时,使用IN,EXISTS都不合适,要使用连接:

  0select * from A left join B on id = A.id

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

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

  这是偶的测试结果:

   set statistics io on 
  0select * from sysobjects where exists (0select 1 from syscolumns
where id=syscolumns.id)
  0select * from sysobjects where id in (0select id from syscolumns )
  set statistics io off

  (47 行受影响)

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

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

  (1 行受影响)

  (44 行受影响)

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

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

  (1 行受影响)

   set statistics io on 
  0select * from syscolumns where exists (0select 1 from sysobjects
where id=syscolumns.id)
  0select * from syscolumns where id in (0select id from sysobjects )
  set statistics io off

  (419 行受影响)

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

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

  (1 行受影响)

  (419 行受影响)

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

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

  (1 行受影响)

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

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

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


相关文章


数据库设计中的14个实用技巧
Oracle中限制返回结果集的行数
获取或记录Oracle语句的执行时间
解决CPU高度消耗(100%)的数据库问题
in和exists的区别与执行效率问题解析
Java中的观察者模式(O erver)学习
Java中重载和重写的区别
使用ecli e调用.netwe ervice
Java编程实现列表框元素动态变化
澳大利亚华人论坛
考好网
日本华人论坛
华人移民留学论坛
英国华人论坛