一、 IN和EXISTS比较

在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行查询。此时就会用到IN和EXISTS。
例如:查询departments表中存在的部门的人数。

1、 使用IN

SQL> set timing on
SQL> select employees.department_id,count(*)
  2  from employees
  3  where employees.department_id in (
  4  select department_id from departments)
  5  group by department_id;

DEPARTMENT_IDCOUNT(*)
------------- ----------
  10      1
  20      2
  30      6
  40      1
  50     45
  60      5
  70      1
  80     34
  90      3
 100      6
 110      2

11 rows selected.

Elapsed: 00:00:00.09

2、 使用EXISTS

SQL> select department_id,count(*)
  2  from employees
  3  where exists(
  4  select 1 from departments where departments.department_id=employees.department_id)
  5  group by employees.department_id;

DEPARTMENT_IDCOUNT(*)
------------- ----------
  10      1
  20      2
  30      6
  40      1
  50     45
  60      5
  70      1
  80     34
  90      3
 100      6
 110      2

11 rows selected.

Elapsed: 00:00:00.01

总结:
IN:确定给定的值是否与子查询或列表中的值相匹配。使用IN时,子查询先产生结果集,然后主查询再去结果集中寻找符合要求的字段列表,符合要求的输出,反之则不输出。
EXISTS:给定一个子查询,检测行的存在。它不返回列表的值,只返回一个True或False。其运行方式是先运行主查询一次,再去子查询中查找与其对应的结果,如果子查询返回True则输出,反之则不输出。再根据主查询中的每一行去子查询中查询。
由于IN操作符需要进行确切地比较,而EXISTS只需要验证存不存在,所以使用IN将会比使用EXISTS花费更多的成本,因此能使用EXISTS替代IN的地方,应该尽量使用EXISTS。另外,尽量使用NOT EXISTS替代NOT IN,使用EXISTS替代DISTINCT。

二、表连接和EXISTS比较

例如:获取部门名为Finance的员工信息

1、 使用EXISTS

SQL> select employee_id,first_name,salary,department_id
  2  from employees
  3  where exists(
  4  select 1 from departments where departments.department_id=employees.department_id
  5  and department_name='Finance');

EMPLOYEE_ID FIRST_NAME    SALARY DEPARTMENT_ID
----------- -------------------- ---------- -------------
108 Nancy
     12008     100
109 Daniel
      9000     100
110 John
      8200     100
111 Ismael
      7700     100
112 Jose Manuel       7800     100
113 Luis
      6900     100

6 rows selected.

Elapsed: 00:00:00.02

2、 使用表连接

SQL> select employee_id,first_name,salary,employees.department_id
  2  from employees,departments
  3  where employees.department_id=departments.department_id
  4  and department_name='Finance';

EMPLOYEE_ID FIRST_NAME    SALARY DEPARTMENT_ID
----------- -------------------- ---------- -------------
108 Nancy
     12008     100
109 Daniel
      9000     100
110 John
      8200     100
111 Ismael
      7700     100
112 Jose Manuel       7800     100
113 Luis
      6900     100

6 rows selected.

Elapsed: 00:00:00.00

从两条SQL语句的执行时间来看,使用连接查询的效率要比使用EXISTS的效率高。当两张表的数据量不大时,使用二者之一就可以,当其中一张表的数据量巨大,或者两张表的数据量都很大的时候,则最好使用连接查询的方式。

【SQL】IN、EXISTS和表连接三者的效率比较的更多相关文章

  1. 读《程序员的SQL金典》[3]--表连接、子查询

    一.表连接-JOIN 1. 自连接实例 查询类型相同的订单信息. SELECT O1 .*,O2.* FROM T_Order O1 JOIN T_Order O2 ON O1 .FTypeId= O ...

  2. SQL Server三种表连接原理

    在SQL Server数据库中,查询优化器在处理表连接时,通常会使用一下三种连接方式: 嵌套循环连接(Nested Loop Join) 合并连接 (Merge Join) Hash连接 (Hash ...

  3. SQL视图和多表连接

    本篇博客关注的焦点是视图的使用以及视图和多表连接的配合.以便可以了解视图,以及更好的使用视图. 首先,还是要说明一下视图的定义:视图是基于SQL语句的结果集的可视化虚拟表,换句话说视图就是SQL查询结 ...

  4. SQL Server中多表连接时驱动顺序对性能的影响

    本文出处:http://www.cnblogs.com/wy123/p/7106861.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...

  5. SQl Server 数据库多表连接

    [缘由] 为了防止数据的冗余,我们会将数据库中表进行拆分,这样就产生了多张表,表与表之间通过主外键关联,但这样又造成了我们查找和修改的困难,如何进行多表之间的查找呢? 我们将一个查询同时设计两个或两个 ...

  6. sql server 实现多表连接查询

    项目中要实现多表查询,用外连接实现. a表 a(aid,aname) 其中aid为pk b表 b(aid,bname,aid) 其中 bid为pk,aid为fk c表 c(cid,cname,aid) ...

  7. SQL Server 2012 - 多表连接查询

    -- 交叉连接产生笛卡尔值 (X*Y) SELECT * FROM Student cross Join dbo.ClassInfo --另外一种写法 SELECT * FROM Student , ...

  8. Sql中EXISTS与IN的使用及效率

    in 和exists 对于以上两种查询条件,in是把外表和内表作hash 连接,而exists 是对外表作loop 循环,每次loop 循环再对内表进行查询. 一直以来认为exists 比in 效率高 ...

  9. MySQL多表连接

    主要分3种:内连接,外连接,交叉连接 其        他:联合连接,自然连接 1.内联接 典型的联接运算,使用像 =  或 <> 之类的比较运算).包括相等联接和自然联接. 内联接使用比 ...

随机推荐

  1. 2.git进阶篇总结

    阅读 Git 原理详解及实用指南 记录 进阶 1 - HEAD.master 与 branch: 介绍了 Git 中的一些「引用」:HEAD.master.branch.这里总结一下: HEAD 是指 ...

  2. Laradock 快速搭建PHP开发环境

    可能你并不清楚 Docker 是什么,更不了解 Laradock是什么,送上语句自己特别喜欢的一句话 Use Docker First And Learn About It Later 大概意思就是 ...

  3. 一个电商项目的Web服务化改造2:现有项目的5个问题

         最近一直在做一个电商项目,需要把原有单系统架构的项目,改造成基于服务的架构,SOA.      有点挑战,做完了,会有很大进步, 1.现有项目的问题   1.1代码风格不统一     不同的 ...

  4. Huawei-R&S-网络工程师实验笔记20190609-VLAN划分综合(Hybrid端口)

    >Huawei-R&S-网络工程师实验笔记20190609-VLAN划分综合(Hybrid端口) >>实验开始,先上拓扑图参考: >>>实验目标:分别实现主 ...

  5. PHP array_intersect_assoc()

    定义和用法 array_intersect_assoc() 函数返回两个或多个数组的交集数组. 与 array_intersect() 函数 不同的是,本函数除了比较键值,还比较键名.返回的数组中元素 ...

  6. [PWA] Show Notifications when a Service Worker is Installed or Updated

    Service Workers get installed and activated in the background, but until we reload the page they don ...

  7. Rust 中项目构建管理工具 Cargo简单介绍

    cargo是Rust内置的项目管理工具.用于Rust 项目的创建.编译.执行,同一时候对项目的依赖进行管理,自己主动推断使用的第三方依赖库,进行下载和版本号升级. 一.查看 cargo 版本号 安装R ...

  8. hibernate之关于一对一单向,双向关联映射

    [hibernate]之关于一对一单向,双向关联映射 首先我们来看,Hibernate官方对于一对一单向关联的解释: 基于外键关联的单向一对一关联和单向多对一关联差点儿是一样的. 唯一的不同就是单向一 ...

  9. jeecg-easypoi-2.0.3版本号公布

    EasyPOI是在jeecg的poi模块基础上,继续开发独立出来的,能够说是2.0版本号,EasyPoi封装的目的和jeecg一致,争取让大家write less do more ,在这个思路上eas ...

  10. ListView无障碍识别整个listView,不识别item,设置了setContentDescription也没实用

    点击ListView的时候.无障碍识别到的是整个listView,不会读点击的那个item. 解决的方法是在getView里手动设置: <span style="font-size:1 ...