In与Exists的区别

这两个函数是差不多的,但由于优化方案不同,通常NOT Exists要比NOT IN要快,因为NOT EXISTS可以使用结合算法二NOT IN就不行了,而EXISTS则不如IN快,因为这时候IN可能更多的使用结合算法。

Select * from tableA Where exists(Select * From tableB Where tableB.ID=tableA.ID)

这句相当于:Select * from tableA Where id in (Select ID From tableB)

对于表tableA的每一条数据,都执行Select * From tableB Where tableB.ID=tableA.ID的存在性判断,如果表tableB中存在表tableA当前行相同的ID,则Exists为真,该行显示,否则不显示。

  • IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况
  • In确定给定的值是否与子查询或列表中的值相匹配
  • Exists指定一个子查询,检测行的存在

-----IN 和NOT IN-----

----哪些部门中有雇员工资大于?-----

select * from Department where Department.deptID=

(select FDeptID from Employee where Employee.empSalary>7000)

----报错信息如下:子查询返回的值多于一个........

----Msg 512, Level 16, State 1, Line 1

----Subquery returned more than 1 value. This is not permitted when the

----subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.---

----改正:将“=”改为“in”

select * from Department where Department.deptID in

(select FDeptID from Employee where Employee.empSalary>7000)

go

----not in

select * from Department where Department.deptID in

(select FDeptID from Employee where Employee.empSalary>7000)

go

-----EXISTS 和NOT EXISTS-----一般用于IF语句的存在检测

----工资改革,检查雇员工资,达到以上的,每人提高,否则每人提高-----

/*--采用EXISTS子查询,进行酌情提升--*/

select * from Employee

go

if exists (select * from Employee where empSalary>7000)

begin

Print ‘有人工资达到,则每人提高,提高后工资为:‘

update Employee set empSalary=empSalary+300

select * from Employee

end

else

begin

Print ‘无人工资达到,则每人提高,提高后工资为:‘

update Employee set empSalary=empSalary+500

select * from Employee

end

go

----IN和Exists---

Select distinct deptName from Department

where exists(select * from Employee where empGender=1)

go

Select distinct deptName from Department

where deptID in(select FDeptID from Employee where empGender=1)

go

----exists相当于存在量词:表示集合存在,也就是集合不为空只作用于一个集合。

----exists P表示P不为空时为真;not Exists P表示P为空时,为真。

----in表示一个标量和医院关系的关系。s In P表示当s与P中的某个值相等时为真;

----s not in P表示s与P中的每一个值都不相等时,为真。

in和exists
in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。一直以来认为exists比in效率高的说法是不准确的。
如果查询的两个表大小相当,那么用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要快。

not in 逻辑上不完全等同于not exists,如果你误用了not in,小心你的程序存在致命的BUG:

请看下面的例子:
create table t1 (c1 number,c2 number);
create table t2 (c1 number,c2 number);

insert into t1 values (1,2);
insert into t1 values (1,3);
insert into t2 values (1,2);
insert into t2 values (1,null);

select * from t1 where c2 not in (select c2 from t2);
no rows found
select * from t1 where not exists (select 1 from t2 where t1.c2=t2.c2);
c1 c2
1 3
[这里涉及到数据的null值的处理,因为null代表着无法预知]。
正如所看到的,not in 出现了不期望的结果集,存在逻辑错误。如果看一下上述两个select语句的执行计划,也会不同。后者使用了hash_aj。
因此,请尽量不要使用not in(它会调用子查询),而尽量使用not exists(它会调用关联子查询)。如果子查询中返回的任意一条记录含有空值,则查询将不返回任何记录,正如上面例子所示。
除非子查询字段有非空限制,这时可以使用not in ,并且也可以通过提示让它使用hasg_aj或merge_aj连接

A:  用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’)B:  用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);

采集

#HUABAN_WIDGETS .HUABAN-red-normal-icon-button, .HUABAN-red-large-icon-button, .HUABAN-red-small-icon-button, .HUABAN-white-normal-icon-button, .HUABAN-white-large-icon-button, .HUABAN-white-small-icon-button { background-image: url({{imgBase}}/widget_icons_ie6.png)

采集

#HUABAN_WIDGETS .HUABAN-red-normal-icon-button, .HUABAN-red-large-icon-button, .HUABAN-red-small-icon-button, .HUABAN-white-normal-icon-button, .HUABAN-white-large-icon-button, .HUABAN-white-small-icon-button { background-image: url({{imgBase}}/widget_icons_ie6.png)

采集

#HUABAN_WIDGETS .HUABAN-red-normal-icon-button, .HUABAN-red-large-icon-button, .HUABAN-red-small-icon-button, .HUABAN-white-normal-icon-button, .HUABAN-white-large-icon-button, .HUABAN-white-small-icon-button { background-image: url({{imgBase}}/widget_icons_ie6.png)

采集

#HUABAN_WIDGETS .HUABAN-red-normal-icon-button, .HUABAN-red-large-icon-button, .HUABAN-red-small-icon-button, .HUABAN-white-normal-icon-button, .HUABAN-white-large-icon-button, .HUABAN-white-small-icon-button { background-image: url({{imgBase}}/widget_icons_ie6.png)

时间: 2024-10-16 09:39:15

In与Exists的区别的相关文章

Sql语句中IN和exists的区别及应用

表展示 首先,查询中涉及到的两个表,一个user和一个order表,具体表的内容如下: user表: order表: in 确定给定的值是否与子查询或列表中的值相匹配.in在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选.所以相对内表比较小的时候,in的速度较快. 具体sql语句如下: 1 SELECT 2 * 3 FROM 4 `user` 5 WHERE 6 `user`.id IN ( 7 SELECT 8 `order`.user_id 9 FROM

sql-in/not in和exists/not exists的区别

In和Exists的区别 这两个函数是差不多的,但由于优化方案不同,通常NOT Exists要比NOT IN要快,因为NOT EXISTS可以使用结合算法二NOT IN就不行了,而EXISTS则不如IN快,因为这时候IN可能更多的使用结合算法. Select * from tableA Where exists(Select * From tableB Where tableB.ID=tableA.ID) 这句相当于: Select * from tableA Where id in (Sele

in和exists的区别与SQL执行效率

in和exists的区别与SQL执行效率最近很多论坛又开始讨论in和exists的区别与SQL执行效率的问题,本文特整理一些in和exists的区别与SQL执行效率分析 SQL中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 * fro

转【】浅谈sql中的in与not in,exists与not exists的区别_

浅谈sql中的in与not in,exists与not exists的区别 1.in和exists in是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询,一直以来认为exists比in效率高的说法是不准确的.如果查询的两个表大小相当,那么用in和exists差别不大:如果两个表中一个较小一个较大,则子查询表大的用exists,子查询表小的用in: 例如:表A(小表),表B(大表) select * from A where cc in(sele

SQL : IN 和 Exists 的区别

Sql语句中IN和exists的区别及应用 表展示 首先,查询中涉及到的两个表,一个user和一个order表,具体表的内容如下: user表: order表: in 确定给定的值是否与子查询或列表中的值相匹配.in在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选.所以相对内表比较小的时候,in的速度较快. 具体sql语句如下: SELECT * FROM user WHERE user.id IN ( SELECT order.user_id FROM o

in 和 exists的区别

区别及应用场景 in 和 exists的区别: 如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用in, 反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用exists.其实我们区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询,所以我们会以驱动表的快速返回为目标,那么就会考虑到索引及结果集的关系了 ,另外IN时不对NULL进行处理. in 是把外表和内表作hash 连

(转)MySQL中In与Exists的区别

背景:总结mysql相关的知识点. 如果A表有n条记录,那么exists查询就是将这n条记录逐条取出,然后判断n遍exists条件. select * from user where exists select * from user); #等价于 select * from user where exists (select 1); in查询就是先将子查询条件的记录全都查出来,假设结果集为B,共有m条记录,然后再将子查询条件的结果集分解成m个,再进行m次查询. select * from us

in和exists的区别以及exists和distinct去重的区别?

小编相信大家都知道in和exists的区别:1.运用情况不同sql中in适用于子查询得出的结果集记录较少,主查询中的表较大且又有索引的表,.sql中exist适用于外层的主查询记录较少,子查询中的表大,又有索引的时候. 2.驱动顺序不同IN是先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选.exists是以外层表为驱动表,先被访问. 3.底层原理不同in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询. 但是我昨天看到

【MySQL】IN 的学习,以及和 EXISTS的区别

1. EXISTS 的语法 语法: EXISTS subquery 参数: subquery 是一个受限的 SELECT 语句 (不允许有 COMPUTE 子句和 INTO 关键字). 结果类型: Boolean 如果子查询包含行,则返回 TRUE ,否则返回 FLASE . 说明: EXISTS (包括 NOT EXISTS) 子句的返回值是一个 BOOL 值. EXISTS 内部有一个子查询语句 (SELECT ... FROM...), 我将其称为 EXIST 的内查询语句.其内查询语句返

Sql 语句中 IN 和 EXISTS 的区别及应用

演示demo表: student表 DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `stuid` varchar(16) NOT NULL COMMENT '学号', `stunm` varchar(20) NOT NULL COMMENT '学生姓名', PRIMARY KEY (`stuid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ------------------------