① sql语句中IN和exists的区别及应用
in和exists
in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。
如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:
例如:表A(小表),表B(大表)1:select * from A where cc in (select cc from B)
效率低,用到了A表上cc列的索引;select * from A where exists(select cc from B where cc=A.cc)
效率高,用到了B表上cc列的索引。
相反的2:select * from B where cc in (select cc from A)
效率高,用到了B表上cc列的索引;select * from B where exists(select cc from A where cc=B.cc)
效率低,用到了A表上cc列的索引。
not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。
in 与 =的区别
select name from student where name in ('zhang','wang','li','zhao');与
select name from student where name='zhang' or name='li' or
name='wang' or name='zhao'
的结果是相同的。
② sql中in和exists的区别效率问题 转
很多人和说法会认为in和Exists相比后者的效率要高。
但是以我本人使用数据库的经验来看,两者的运行效率其实不相伯仲,不管有无可被利用的索引,它们在运行速度上没有太明显的分别,硬要说哪个快一些的话exists可能会快一点点,但是这种区别通常可以忽略。
然而在求非交集时 not in和not exists运行效率上的差距就很大,碰到大数据表时not in不管有无可被利用的索引,都会导致效率悲剧,其运行速度极之糟糕往往要运行很长的时间才能返回结果,期间系统就像假死一样。not exists在有可被利用的索引的情况下碰到大数据表时其运行效率非常高、表现优异,但是若没有可被利用索引的情况下其运行效率也很不好,此时其运行速度尽管要比not in快上不少但还是属于那种令人无法接受的“蜗速”。
in和exists随各人喜好随便用,特别是数据量不大时。面对大数据表时就要小心,not in无论有无可被利用的索引都应避免使用,not exists在有可被利用索引的情况下可作为首选,反之也要避免使用。
③ SQL查询中in和exists的区别分析
1.exist,not exist一般都是与子查询一起使用. In可以与子查询一起使用,也可以直接in (a,b.....)
2.exist会针对子查询的表使用索引. not exist会对主子查询都会使用索引. in与子查询一起使用的时候,只能针对主查询使用索引. not in则不会使用任何索引. 注意,一直以来认为exists比in效率高的说法是不准确的。
in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。
如果查询的两个表大小相当,那么用in和exists差别不大。
如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:
例如:表A(小表),表B(大表)1:select * from A where cc in (select cc from B)
效率低,用到了A表上cc列的索引;select * from A where exists(select cc from B where cc=A.cc)
效率高,用到了B表上cc列的索引。
相反的2:select * from B where cc in (select cc from A)
效率高,用到了B表上cc列的索引;select * from B where exists(select cc from A where cc=B.cc)
效率低,用到了A表上cc列的索引。
not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。
3.exist与in都可以实现一个目的.二者都可以用来过滤数据.
示例:
select count(1) from t1;--160W
select count(1) from t2; --90W
SELECT count(1)
FROM t1 a
WHERE EXISTS (SELECT accountid
FROM t2 b
WHERE a.keyid = b.keyid AND a.ideaid = b.ideaid);--主大子小,不适合使用exist,因为exist只会利用子表t2的复合索引keyid+ideaid,而子表内容要小与主表,主表由于无法使用索引,查询效率低下.
select count(1) from t1 a where accountid in (SELECT accountid
FROM t2 b
WHERE a.keyid = b.keyid AND a.ideaid = b.ideaid);--主大子小,适合用in,因为in只会使用主表t1里面的复合主键keyid-ideaid,在主表大于子表的情况下,会很好的利用主表的索引.
--后二条sql的执行结果都是一样的.说明exist与in在用法上可以达到一个目的,不同的地方是
--1.性能的考虑此时就按子表大主表小用exist,子表小主表大用in的原则就可以.
--2.写法的不同, exist的where条件是: "...... where exist (..... where a.id=b.id)"
--in的where条件是: " ...... where id in ( select id .... where a.id=b.id)"
4. exist的原理:
exists做为where 条件时,是先对where 前的主查询询进行查询,然后用主查询的结果一个一个的代入exists的查询进行判断,如果为真则输出当前这一条主查询的结果,否则不输出
比如
如下:
表A
ID NAME
1 A1
2 A2
3 A3
表B
ID AID NAME
1 1 B1
2 2 B2
3 2 B3
表A和表B是一对多的关系 A.ID --> B.AID
SELECT ID , NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE A.ID = B.AID)
执行结果为
1 A1
2 A2
原因可以按照如下分析
SELECT ID , NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID = 1)
-->SELECT * FROM B WHERE B.AID = 1有值返回真所以有数据
SELECT ID , NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID = 2)
-->SELECT * FROM B WHERE B.AID = 2有值返回真所以有数据
SELECT ID , NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID = 3)
-->SELECT * FROM B WHERE B.AID = 3无值返回真所以没有数据
NOT EXISTS 就是反过来
SELECT ID , NAME FROM A WHERE NOT EXIST (SELECT * FROM B WHERE A.ID = B.AID)
执行结果为
3 A3
5. in 与 =的区别
select name from student where name in ('zhang','wang','li','zhao');
与
select name from student where name='zhang' or name='li' or name='wang' or name='zhao'
的结果是相同的。
in的字段也可以与其它字段建复合索引.
比如
T1包含下面key, accountd,groupid.
SELECT *
FROM T1 a
WHERE a.groupid = 2001
AND a.accountid = 1001
AND a.key IN ('abc', 'def', 'ala');
--上面的sql可以将accountid,key建成复合索引.
④ SQL语句中“in”和“exist”有什么区别
本文主要分析了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 次
⑤ sql中in和exist语句的区别
两者都能实现表功能查询,主要区别如下:
1、适用表的类型不同。
in是子查询为驱动表,外面的表为被驱动表,故适用于子查询结果集小而外面的表结果集大的情况。
exists是外面的表位驱动表,子查询里面的表为被驱动表,故适用于外面的表结果集小而子查询结果集大的情况。
2、子查询关联不同。
exists一般都是关联子查询。对于关联子查询,必须先执行外层查询,接着对所有通过过滤条件的记录,执行内层查询。外层查询和内层查询相互依赖,因为外层查询会把数据传递给内层查询。
in则一般都是非关联子查询,非关联子查询则必须先完成内层查询之后,外层查询才能介入。
3、执行次数不同。
IN 语句:只执行一次,确定给定的值是否与子查询或列表中的值相匹配。in在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选。所以相对内表比较小的时候,in的速度较快。
EXISTS语句:执行次数根据表的长度而定。指定一个子查询,检测行的存在。遍历循环外表,然后看外表中的记录有没有和内表的数据一样的。匹配上就将结果放入结果集中。
⑥ SQL关于IN和EXISTS的区别
IN
确定给定的值是否与子查询或列表中的值相匹配。
EXISTS
指定一个子查询,检测行的存在。
比较使用 EXISTS 和 IN 的查询
exists()后面的子查询被称做相关子查询 他是不返回列表的值的.只是返回一个ture或false的结果,其运行方式是先运行主查询一次 再去子查询里查询与其对应的结果 如果是ture则输出,反之则不输出.再根据主查询中的每一行去子查询里去查询.
in()后面的子查询 是返回结果集的,换句话说执行次序和exists()不一样.子查询先产生结果集,然后主查询再去结果集里去找符合要求的字段列表去.符合要求的输出,反之则不输出.
⑦ sql中in和exists的具体区别
使用in的时候,执行过程不能使用索引;使用exists的时候,可以使用索引,所定义一般情况下,exists效率高些。(要看具体情况,如表的大小,驱动表的选择)
⑧ SQL中 exists和in的区别是什么啊
11. 用EXISTS替代IN、用NOT EXISTS替代NOT IN
在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接.在这种情况下, 使用EXISTS(或NOT EXISTS)通常将提高查询的效率. 在子查询中,NOT IN子句将执行一个内部的排序和合并. 无论在哪种情况下,NOT IN都是最低效的 (因为它对子查询中的表执行了一个全表遍历). 为了避免使用NOT IN ,我们可以把它改写成外连接(OUTER JOINS)或NOT EXISTS.
例子:(高效)SELECT * FROM EMP (基础表) WHERE EMPNO > 0 AND EXISTS (SELECT ‘X' FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB’)
(低效)SELECT * FROM EMP (基础表) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = ‘MELB’)
12. 用EXISTS替换DISTINCT
当提交一个包含一对多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT. 一般可以考虑用EXIST替换, EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果。
例:(低效): SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E WHERE D.DEPT_NO = E.DEPT_NO
(高效): SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT ‘X' FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);
⑨ SQL中IN和EXISTS用法的区别
IN的用法:列名 IN(子查询),IN子查询是将IN前面列的值与子查询返回的值进行比较,如果子查询中返回的值中与列名的取值有匹配的值,则条件成立,所以子查询中必须返回一列值,且只能返回一列值。
EXISTS的用法:EXISTS(子查询) ,EXISTS是一个函数,是根据子查询中有无记录返回确定条件是否成立,如果子查询有记录返回,则条件成立;如果子查询无记录返回,则条件不成立。由于EXISTS只是根据子查询有无记录返回确定条件是否成立,并不关心返回的是何值,因此子查询给出列名无意义,因此子查询的目标列通常是*,即语句格式为:
EXISTS(SELECT * FROM 表 WHERE 条件)
⑩ 关于查询语句中的in和exists的区别
1、适用表的类型不同。
in是子查询为驱动表,外面的表为被驱动表,故适用于子查询结果集小而外面的表结果集大的情况。
exists是外面的表位驱动表,子查询里面的表为被驱动表,故适用于外面的表结果集小而子查询结果集大的情况。
2、子查询关联不同。
exists一般都是关联子查询。对于关联子查询,必须先执行外层查询,接着对所有通过过滤条件的记录,执行内层查询。外层查询和内层查询相互依赖,因为外层查询会把数据传递给内层查询。
in则一般都是非关联子查询,非关联子查询则必须先完成内层查询之后,外层查询才能介入。
3、执行次数不同。
IN 语句:只执行一次,确定给定的值是否与子查询或列表中的值相匹配。in在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选。所以相对内表比较小的时候,in的速度较快。
EXISTS语句:执行次数根据表的长度而定。指定一个子查询,检测行的存在。遍历循环外表,然后看外表中的记录有没有和内表的数据一样的。匹配上就将结果放入结果集中。
SQL语句语言特点:
1、SQL风格统一
SQL可以独立完成数据库生命周期中的全部活动,包括定义关系模式、录人数据、建立数据库、査询、更新、维护、数据库重构、数据库安全性控制等一系列操作,这就为数据库应用系统开发提供了良好的环境,在数据库投入运行后,还可根据需要随时逐步修改模式,且不影响数据库的运行,从而使系统具有良好的可扩充性。
2、高度非过程化
非关系数据模型的数据操纵语言是面向过程的语言,用其完成用户请求时,必须指定存取路径。而用SQL进行数据操作,用户只需提出“做什么”,而不必指明“怎么做”,因此用户无须了解存取路径,存取路径的选择以及SQL语句的操作过程由系统自动完成。这不但大大减轻了用户负担,而且有利于提高数据独立性。