SQL中的in和exists的区别

来源:互联网 发布:炒股用什么软件 编辑:程序博客网 时间:2024/05/21 10:27

在网上看到一个很好的例子讲解in和exists的区别,这里备忘下。

本示例所示查询查找由位于以字母 B 开头的城市中的任一出版商出版的书名:
USE pubs

SELECT title
FROM titles WHERE EXISTS
    (
SELECT *
   
FROM publishers
   
WHERE pub_id = titles.pub_id
   
AND city LIKE  'B%')
GO

-- Or, using IN:

USE pubs
GO
SELECT title
FROM titles
WHERE pub_id IN
    (
SELECT pub_id
   
FROM publishers
   
WHERE city LIKE  'B%')
GO 


使用
NOT EXISTS

NOT EXISTS 的作用与 EXISTS 正相反。如果子查询没有返回行,则满足 NOT EXISTS 中的 WHERE
子句。本示例查找不出版商业书籍的出版商的名称:

USE pubs
GO
SELECT pub_name
FROM publishers
WHERE NOT EXISTS
    (
SELECT *
   
FROM titles
   
WHERE pub_id = publishers.pub_id
   
AND type = 'business')
ORDER BY pub_name
GO

 

 

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

的结果是相同的。

 

in和exists的SQL执行效率分析

  A,B两个表,

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

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

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

  select * from A

  where 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

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

原创粉丝点击