in 和exists

对于以上两种查询条件,in是把外表和内表作hash 连接,而exists 是对外表作loop 循环,每次loop 循环再对内表进行查询。

一直以来认为exists 比in 效率高的说法是不准确的。在不同的情况下,exists与in的性能各有优缺项,如果查询的两个表大小相当,那么用in 和exists 差别不大。

下面以实例来进行说明:

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

select *  from A where exists (select 1 from B where A.id = B.id);

1、in的应用原理

在select *  from A where id in(select id from B); 中,in()中的子查询只执行一次,它查询出B表中的所有ID值并缓存起来;之后,在内存中检查A表的id是否与B表中的id值相等,如果相等则则将A表的记录加入到结果集中,直到遍历完A表中的所有记录。

它查询的过程类似于一下过程

Array A={select * from A};
Array B={select id from B};
for (int i=0;i<A.length;i++){for (int j=0;j<B.length;j++){if (A[i].id == B[j].id){ resultSet.add(A[i]);break;}}
}

如:A表有10000条记录,B表有1000000条记录,那么使用in最多可能有10000*1000000次遍历,效率很差;

A表有10000条记录,B表有100条记录,那么使用in最多可能有10000*100次遍历,遍历次数大大减少,效率大大提升;

结论:in()适合B表比A表数据小的情况

2、exists的应用原理

在select * from A where exists (select 1 from B where A.id=B.id);之中
exists()会执行A.length次,它并不缓存exists()结果集,因为exists()结果集的内容并不重要,重要的是其内查询语句的结果集空或者非空,空则返回false,非空则返回true。
它的查询过程类似于以下过程:

Array A=(select * from A);
for(int i=0;i<A.length;i++) {  if(exists(A[i].id) {  //执行select 1 from B where B.id=A.id是否有记录返回  resultSet.add(A[i]);  }
}
return resultSet;

当B表比A表数据大时适合使用exists(),因为它没有那么多遍历操作,只需要再执行一次查询就行。
如:A表有10000条记录,B表有1000000条记录,那么exists()会执行10000次去判断A表中的id是否与B表中的id相等。
如:A表有10000条记录,B表有100000000条记录,那么exists()还是执行10000次,因为它只执行A.length次,可见B表数据越多,越适合exists()发挥效果。
再如:A表有10000条记录,B表有100条记录,那么exists()还是执行10000次,还不如使用in()遍历10000*100次,因为in()是在内存里遍历比较,而exists()需要查询数据库,我们都知道查询数据库所消耗的性能更高,而内存比较很快

结论:exists()适合B表比A表数据大的情况

当A表数据与B表数据一样大时,in与exists效率差不多,可任选一个使用。

数据从一个表往另外一个表中插入数据时使用EXISTS:

在插入记录前,需要检查这条记录是否已经存在,只有当记录不存在时才执行插入操作,可以通过使用 EXISTS 条件句防止插入重复记录。
insert into A (name,age) select name,age from B where not exists (select 1 from A where A.id=B.id);

EXISTS与IN的使用效率的问题,通常情况下采用exists要比in效率高,因为IN不走索引。但要看实际情况具体使用:IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。

关于EXISTS:
EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值TRUE 或FLASE 。
EXISTS指定一个子查询,检测行的存在。
语法:EXISTS subquery
参数:subquery 是一个受限的 SELECT 语句 (不允许有 COMPUTE 子句和 INTO 关键字)。
结果类型:Boolean 如果子查询包含行,则返回 TRUE ,否则返回 FLASE 。
结论:select * from A where exists (select 1 from B where A.id=B.id) 
EXISTS(包括 NOT EXISTS )子句的返回值是一个boolean值。 EXISTS内部有一个子查询语句(SELECT ... FROM...), 我将其称为EXIST的内查询语句。其内查询语句返回一个结果集。 EXISTS子句根据其内查询语句的结果集空或者非空,返回一个布尔值。
一种通俗的可以理解为:将外查询表的每一行,代入内查询作为检验,如果内查询返回的结果取非空值,则EXISTS子句返回TRUE,这一行行可作为外查询的结果行,否则不能作为结果。
分析器会先看语句的第一个词,当它发现第一个词是SELECT关键字的时候,它会跳到FROM关键字,然后通过FROM关键字找到表名并把表装入内存。接着是找WHERE关键字,如果找不到则返回到SELECT找字段解析,如果找到WHERE,则分析其中的条件,完成后再回到SELECT分析字段。最后形成一张我们要的虚表。
WHERE关键字后面的是条件表达式。条件表达式计算完成后,会有一个返回值,即非0或0,非0即为真(true),0即为假(false)。同理WHERE后面的条件也有一个返回值,真或假,来确定接下来执不执行SELECT。

转载:https://www.cnblogs.com/niudaxianren/p/10018634.html

SQL中EXISTS与IN的使用及效率相关推荐

  1. SQL中EXISTS理解使用

    SQL中EXISTS的理解使用 关联子查询 EXISTS理解使用 关联子查询 在讲述EXISTS用法之前,先讲述一下关联子查询: 关联子查询:是指在内查询中需要借助于外查询,而外查询离不开内查询的执行 ...

  2. sql中exists替换in的区别

    在sql中使用exists替换in查询时要注意使用exists时一定要关联主查询和子查询的关联不然查询会得不到相应的结果如下语句:  语句一使用in查询:  select realname from ...

  3. sql中exists,not exists的用法

    exists : 强调的是是否返回结果集,不要求知道返回什么, 比如:   select name from student where sex = 'm' and mark exists(selec ...

  4. SQL中EXISTS的使用

    1.简介 2.表结构 3.查询所有选修了"C1"课程的学生名. 4.查询没有选C1课程的学生的学号.姓名 5.查询选修了所有课程的学生的姓名(续) 6.查询至少选修了S1所选的全部 ...

  5. SQL中exists关键字的用法

    exists用于检查一个子查询是否至少会返回一行数据(即检测行的存在),返回值为true或false.         语法: exists subquery         参数: subquery ...

  6. sql中exists用法

    exists关键字介绍 exists强调的是 是否返回结果集,不要求知道返回什么,比如: SELECT * FROM AM_USER WHERE EXISTS (SELECT 1 FROM AM_RO ...

  7. SQL中EXISTS的用法以及和IN的区别

    感谢大神分享,原链接在此 http://www.cnblogs.com/xuanhai/p/5810918.html (原文中有实例,非常不错,我是搬运工) 关于 EXISTS的使用 EXISTS(包 ...

  8. java中exists是什么_JAVA:sql中exists的用法

    exists:强调的是是否返回结果集,不要求知道返回什么,比如:selectnamefromstudentwheresex='m'andmarkexists(select1fromgradewhere ...

  9. SQL中EXISTS的用法(转)

    比如在Northwind数据库中有一个查询为 SELECT c.CustomerId,CompanyName FROM Customers c WHERE EXISTS( SELECT OrderID ...

最新文章

  1. 如果地府需要一个后台管理系统,你会如何设计?
  2. 深入Bert实战(Pytorch)----fine-Tuning 2
  3. spring el表达式 if else_vue指令集合:v-for,v-show,v-if等
  4. Vista 系统C盘(系统盘)越来越小的问题.与解决.
  5. IBASE component deletion
  6. 移动设备应用程序开发入门一:创建用于设备的 Windows 窗体应用程序并打包进行部署...
  7. [BZOJ1001]: [BeiJing2006]狼抓兔子
  8. mysql 命令导出excel
  9. weblogic12升级jdk_如何修改WEBLOGIC的JDK版本
  10. 美团“共享单车变球场”项目落地四川阿坝
  11. Day27:threading模块
  12. 二叉树——基本知识+python实现
  13. Hadoop CentOS 7 安装配置
  14. 【HDU1166】敌兵布阵(树状数组或线段树)
  15. webform 组合查询
  16. 用数据分析的手段,看2019年CSDN博客之星总评选
  17. 计算机控制系统在电厂的应用,【2017年整理】计算机控制系统在火电厂中的应用...
  18. 《基因大数据智能生产及分析》笔记
  19. LLVM IR / LLVM指令集入门
  20. 小明发布_每日LOL圈:LPL春季赛将于13号开赛;小明、阿水、Meiko多人聚餐

热门文章

  1. java中字符串判断相等能用不等号吗
  2. SortExpression的用法问题
  3. chromebook刷机_适用于Chromebook和PC的传统台式机应用程序的30多种基于Web的替代品...
  4. EASYPOI导入报错The part /xl/drawings/drawing1.xml failed to be saved
  5. linux输完命令如何回退,linux 常用命令
  6. 如此取名可防IP被封
  7. sql 四舍五入后补零
  8. android 效果集合
  9. 西普教育:发挥高校示范引领作用 助力新工科建设
  10. The Lion, The Bear And The Fox