sql语句中in与exist not in与not exist 的区别

in和exists

in 是把外表和内表作hash
连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。一直以来认为exists比in效率高的说法是不准确的。

如果查询的两个表大小相当,那么用in和exists差别不大。

全文:

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要快。

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‘

的结果是相同的。

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

正如所看到的,not in
出现了不期望的结果集,存在逻辑错误。如果看一下上述两个select语句的执行计划,也会不同。后者使用了hash_aj。

因此,请尽量不要使用not
in(它会调用子查询),而尽量使用not
exists(它会调用关联子查询)。如果子查询中返回的任意一条记录含有空值,则查询将不返回任何记录,正如上面例子所示。

除非子查询字段有非空限制,这时可以使用not
in ,并且也可以通过提示让它使用hasg_aj或merge_aj连接。

时间: 2024-10-10 06:28:25

sql语句中in与exist not in与not exist 的区别的相关文章

sql语句中left join、right join、inner join的区别

left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录: right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录:inner join(等值连接) 只返回两个表中联结字段相等的行. 我们建立两个简单的表A和B,如图所示: A:     B: 1)left join 我们执行sql语句:select * from A left join B  on A.id = B.id; 结果如下: 说明:left join是以A表的记录为基础的,A可以看成

SQL点滴35—SQL语句中的exists

原文:SQL点滴35-SQL语句中的exists 比如在Northwind数据库中有一个查询为 SELECT c.CustomerId,CompanyName FROM Customers c WHERE EXISTS( SELECT OrderID FROM Orders o WHERE o.CustomerID=c.CustomerID) 这里面的EXISTS是如何运作呢?子查询返回的是OrderId字段,可是外面的查询要找的是CustomerID和CompanyName字段,这两个字段肯定

回顾sql语句中的各种连接

1. 内连接(Inner Join) 内连接是最常见的一种连接,它页被称为普通连接,而E.FCodd最早称之为自然连接. 下面是ANSI SQL-92标准 select * from    t_institution i inner join t_teller t on i.inst_no = t.inst_no where i.inst_no = "5801" 其中inner可以省略. 等价于早期的连接语法 select * from t_institution i, t_telle

oracle sql语句中使用if逻辑

l在 SQL 语句中使用IF-THEN-ELSE 逻辑 l l使用两种方法: •CASE 表达式:SQL99的语法,类似Basic,比较繁琐 •DECODE 函数:Oracle自己的语法,类似Java,比较简介 1 SQL> select ename,job, sal, case job when 'PRESIDENT' then 1.1*sal 2 2 when 'MANAGER' then 1.2*sal 3 3 when 'CLERK' then 1.3*sal 4 4 else 1.4*

SQL语句中DateAdd 函数说明

实践例子: 将借阅表中所有记录的归还日期加15天: 执行前情况: 执行后情况如下: update 借阅 set 归还日期=DateAdd ("D",15,归还日期) [详细讲解:] 返回 返回包含一个日期的 Variant (Date),这一日期还加上了一段时间间隔. 语法 DateAdd(interval, number, date) DateAdd 函数语法中有下列命名参数: interval 必要.字符串表达式,是所要加上去的时间间隔. number 必要.数值表达式,是要加上的

select 1 from ... sql语句中的1解读

摘自:http://blog.csdn.net/zengcong2013/article/details/48224509 select  1 from ..., sql语句中的1代表什么意思?查出来是个什么结果?         select 1 from table;与select anycol(目的表集合中的任意一行) from table;与select * from table 从作用上来说是没有差别的,都是查看是否有记录,一般是作条件查询用的.select 1 from 中的1是一常

关于SQL语句中SUM函数返回NULL的解决办法

SUM 是SQL语句中的标准求和函数,如果没有符合条件的记录,那么SUM函数会返回NULL. 但多数情况下,我们希望如果没有符合条件记录的情况下,我们希望它返回0,而不是NULL,那么我们可以使用例如下面的方法来处理: SELECT COALESCE(SUM(name),0) FROM person WHERE id > 0   行了,这下就不用费事去处理返回结果是否为NULL的情况了. COALESCE 函数的意思是返回参数列表中第一个为空的值,该方法允许传入多个参数,该函数也是SQL中的标准

关于在java中向带有IN的SQL语句中传参数的问题

今天遇到俩个问题: 1.在使用表格模型的时候,从数据库查询出来的数据赋值到Jtable的时候永远只显示最后一天记录,前面的都被覆盖了.一直在究其原因,未果,遂择其道而行之(第二个问题). 2.为了解决上面的问题,我将SQL语句的条件换成IN,目的想把所有参数一并传过去,查询所有记录后在一并显示到Jtable上,实验证明我的做法是对的.但是,一直没有搞懂IN(?)这个问号应该如何传值. SQL : String sql = " select sxh,grbm,xm,yybm,fyze,qzfbf,

SQL语句中常用关键词及其解释如下.pdf

SQL语句中常用关键词及其解释如下.pdf 路径 C:\Users\Administrator\Desktop\ 大小 1.18 MB 类型 PDF 文件 修改日期 2016年12月1日 16:50:15 文件被导入 2016年12月1日 17:02:34 附件列表

SQL语句中SUM与COUNT的区别

SUM是对符合条件的记录的数值列求和 COUNT 是对查询中符合条件的结果(或记录)的个数 例如: 表fruit id     name    price 1     apple     3.00 2     pear       4.00 select count(price) from fruit; ----执行之后结果为:2  (表示有2条记录) select  sum(price) from fruit;---执行之后结果为:7:00(表示各记录price字段之和为7.00) SQL语句