浅谈sql中的in与not in,exists与not exists的区别

 

1、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列的索引;
  2.  
  3. select * from A where exists(select cc from B where cc=A.cc)  -->效率高,用到了B表上cc列的索引。

相反的:

  1. select * from B where cc in(select cc from A)  -->效率高,用到了B表上cc列的索引
  2.  
  3. select * from B where exists(select cc from A where cc=B.cc)  -->效率低,用到了A表上cc列的索引。

2、not in 和not exists

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

  1. create table #t1(c1 int,c2 int);
  2.  
  3. create table #t2(c1 int,c2 int);
  4.  
  5. insert into #t1 values(1,2);
  6.  
  7. insert into #t1 values(1,3);
  8.  
  9. insert into #t2 values(1,2);
  10.  
  11. insert into #t2 values(1,null);
  12.  
  13. select * from #t1 where c2 not in(select c2 from #t2);  -->执行结果:无
  14.  
  15. select * from #t1 where not exists(select 1 from #t2 where #t2.c2=#t1.c2)  -->执行结果:1  3

正如所看到的,not in出现了不期望的结果集,存在逻辑错误。如果看一下上述两个select 语句的执行计划,也会不同,后者使用了hash_aj,所以,请尽量不要使用not in(它会调用子查询),而尽量使用not exists(它会调用关联子查询)。如果子查询中返回的任意一条记录含有空值,则查询将不返回任何记录。如果子查询字段有非空限制,这时可以使用not in,并且可以通过提示让它用hasg_aj或merge_aj连接。

如果查询语句使用了not in,那么对内外表都进行全表扫描,没有用到索引;而not exists的子查询依然能用到表上的索引。所以无论哪个表大,用not exists都比not in 要快。

3、in 与 = 的区别

  1. select name from student where name in('zhang','wang','zhao');

  1. select name from student where name='zhang' or name='wang' or name='zhao'

的结果是相同的。

转【】浅谈sql中的in与not in,exists与not exists的区别_的更多相关文章

  1. 浅谈sql中的in与not in,exists与not exists的区别

    转 浅谈sql中的in与not in,exists与not exists的区别   12月12日北京OSC源创会 —— 开源技术的年终盛典 »   sql exists in 1.in和exists ...

  2. 浅谈sql中的in与not in,exists与not exists的区别以及性能分析

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

  3. 浅谈 sql 中数据的约束

    数据约束 --对用户操作表的数据进行约束 1.默认值 --当用户对使用默认值的字段不插入值的时候,就使用默认值 1)对默认值字段插入null是可以的. 2)对默认值字段可以插入非null [例如:ad ...

  4. 浅谈SQL中的单引号

    单引号:对很对计算机语言包括(SQL)是做字符串引用的:这个是大家通常知道的作用:但是对SQL语言来说:还有另外一个作用是作引号的转义 总结下:对oracle(sql)的作用. 做字符串引用:例如'a ...

  5. 【sql注入】浅谈sql注入中的Post注入

    [sql注入]浅谈sql注入中的Post注入 本文来源:i春秋学院 00x01在许多交流群中,我看见很多朋友对于post注入很是迷茫,曾几何,我也是这样,因为我们都被复杂化了,想的太辅助了所以导致现在 ...

  6. 浅谈MySQL中优化sql语句查询常用的30种方法 - 转载

    浅谈MySQL中优化sql语句查询常用的30种方法 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使 ...

  7. c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程

    c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...

  8. 浅谈SQL注入风险 - 一个Login拿下Server

    前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...

  9. 浅谈sql 、linq、lambda 查询语句的区别

    浅谈sql .linq.lambda 查询语句的区别 LINQ的书写格式如下: from 临时变量 in 集合对象或数据库对象 where 条件表达式 [order by条件] select 临时变量 ...

随机推荐

  1. 深入理解c#(第三版)(文摘)

    第一部分 基础知识 第1章 C#开发的进化史 1.3 1.3.1 表示未知的价格 public decimal? Price { get; private set; } new ProductWith ...

  2. [fortify] 不安全的函数eregi()

    PHP 5.4/5.3弃用函数eregi() memory_limit绕过漏洞 [日期:2012-04-02] 来源:Linux社区  作者:Linux [字体:大 中 小]   发布日期:2012- ...

  3. mysql下载安装

    1.下载 下载地址:http://dev.mysql.com/downloads/mysql/ 根据电脑配置来选,我选了 windows(x86,64-bit),ZIP Archive这个,点击Dow ...

  4. UDP 一个封锁操作被对 WSACancelBlockingCall 的调用中断

    using System; using System.Collections.Generic; using System.Text; using System.Net.Sockets; using S ...

  5. oracle中的函数及其应用

    --..............常用的单行函数......................   -------------------  常用的字符函数  ---------------------- ...

  6. 特征处理(Feature Processing)

    [本文链接:http://www.cnblogs.com/breezedeus/p/4109456.html,转载请注明出处] 我的博客主营地迁至github,欢迎朋友们有空去看看:http://br ...

  7. 用ADMM求解大型机器学习问题

    [本文链接:http://www.cnblogs.com/breezedeus/p/3496819.html,转载请注明出处] 从等式约束的最小化问题说起:                       ...

  8. 工作随笔——Swift中的Range和一些字符操作

    截取字符串在Swift中相比OC要复杂很多,主要原因可能还是OC的NSRange的创建方法中参数类型为int,而Swift却对类型要求很严格,int不能作为参数创建Range,这要使用String中的 ...

  9. iOS 标题内容待定

    UITableView: UITableViewCell的声明文件.所包含的: UIView控件(contentView,作为其它元素的父控件) -- 容器 两个UILabel控件( textLabe ...

  10. WCF服务配置问题

      上一篇中,我们主要是使用了代码来实现服务的自我寄宿.代码的实现稍微复杂些,不过还有些使用配置文件和配置工具的方法.下面来一一介绍下.     1.配置文件.首先在Host下添加个app.confi ...