SQL中in可以分为三类: 形如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',你可能指的不是这一类,这里不做讨论。
SQL中in可以分为三类:
A,B两个表
所以使用何种方式,要根据要求来定。
这是一般情况下做的测试:
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 次。
如果要查询每个类别的最大sid 的话
select * from test a where not exists(select 1 from test where sort = a.sort and sid > a.sid)
比
select * from test a where sid in (select max(sid) from test where sort = a.sort)
的执行效率要高三倍以上。
sql优化中,使用in和exist? 主要是看你的筛选条件是在主查询上还是在子查询上。