SQL : IN 和 Exists 的区别
表展示
首先,查询中涉及到的两个表,一个user和一个order表,具体表的内容如下:
user表:

order表:

in
确定给定的值是否与子查询或列表中的值相匹配。in在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选。所以相对内表比较小的时候,in的速度较快。
具体sql语句如下:
SELECT *
FROM
user
WHERE
user.id IN (
SELECT
order.user_id
FROM
order
)
这条语句很简单,通过子查询查到的user_id 的数据,去匹配user表中的id然后得到结果。该语句执行结果如下:

它的执行流程是什么样子的呢?让我们一起来看一下。
首先,在数据库内部,查询子查询,执行如下代码:
SELECT
order.user_id
FROM
order
执行完毕后,得到结果如下:

此时,将查询到的结果和原有的user表做一个笛卡尔积,结果如下:

此时,再根据我们的user.id IN order.user_id的条件,将结果进行筛选(既比较id列和user_id 列的值是否相等,将不相等的删除)。最后,得到两条符合条件的数据。

exists
指定一个子查询,检测行的存在。遍历循环外表,然后看外表中的记录有没有和内表的数据一样的。匹配上就将结果放入结果集中。
具体sql语句如下:
SELECT*
FROM
user
WHERE
EXISTS (
SELECT
order.user_id
FROM
order
WHERE
user.id = order.user_id
)
这条sql语句的执行结果和上面的in的执行结果是一样的。

但是,不一样的是它们的执行流程完全不一样:
使用exists关键字进行查询的时候,首先,我们先查询的不是子查询的内容,而是查我们的主查询的表,也就是说,我们先执行的sql语句是:
SELECT `user`.* FROM `user`
得到的结果如下:

然后,根据表的每一条记录,执行以下语句,依次去判断where后面的条件是否成立:
EXISTS (
SELECT
order.user_id
FROM
order
WHERE
user.id = order.user_id
)
如果成立则返回true不成立则返回false。如果返回的是true的话,则该行结果保留,如果返回的是false的话,则删除该行,最后将得到的结果返回。
区别及应用场景
in 和 exists的区别: 如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用in, 反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用exists。其实我们区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询,所以我们会以驱动表的快速返回为目标,那么就会考虑到索引及结果集的关系了 ,另外IN时不对NULL进行处理。
in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。一直以来认为exists比in效率高的说法是不准确的。
not in 和not exists
如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。
SQL : IN 和 Exists 的区别的更多相关文章
- 你真的会玩SQL吗?EXISTS和IN之间的区别
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- 转【】浅谈sql中的in与not in,exists与not exists的区别_
浅谈sql中的in与not in,exists与not exists的区别 1.in和exists in是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表 ...
- 浅谈sql中的in与not in,exists与not exists的区别
转 浅谈sql中的in与not in,exists与not exists的区别 12月12日北京OSC源创会 —— 开源技术的年终盛典 » sql exists in 1.in和exists ...
- in和exists的区别与SQL执行效率
in和exists的区别与SQL执行效率最近很多论坛又开始讨论in和exists的区别与SQL执行效率的问题,本文特整理一些in和exists的区别与SQL执行效率分析 SQL中in可以分为三类: 1 ...
- in和exists的区别与SQL执行效率分析
可总结为:当子查询表比主查询表大时,用Exists:当子查询表比主查询表小时,用in SQL中in可以分为三类: 1.形如select * from t1 where f1 in ('a','b'), ...
- 面试被问之-----sql优化中in与exists的区别
曾经一次去面试,被问及in与exists的区别,记得当时是这么回答的:''in后面接子查询或者(xx,xx,xx,,,),exists后面需要一个true或者false的结果",当然这么说也 ...
- SQL in、not in、exists和not exists的区别:
来自:http://blog.sina.com.cn/s/blog_8a0c4f130100zaw2.html 先谈谈in和exists的区别: exists:存在,后面一般都是子查询,当子查询返回行 ...
- Sql语句中IN和exists的区别及应用
表展示 首先,查询中涉及到的两个表,一个user和一个order表,具体表的内容如下: user表: order表: in 确定给定的值是否与子查询或列表中的值相匹配.in在查询的时候,首先查询子查询 ...
- Sql 语句中 IN 和 EXISTS 的区别
IN 语句:只执行一次 确定给定的值是否与子查询或列表中的值相匹配.in在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选.所以相对内表比较小的时候,in的速度较快 ...
随机推荐
- 组合式MapReduce计算作业
1)迭代MapReduce计算任务,就是在一个循环内多次执行一个MapReduce. 2)顺序组合式MapReduce作业的执行 MapReduce1—>MapReduce2—>MapRe ...
- 输入参数之POJO包装类
1,包装类:需要实现序列化 package com.songyan.pojo; import java.io.Serializable; public class QueryVo implements ...
- python可变的参数列表
一般的计算机语言中参数的个数是不能改变的,但是在python中实参的个数是可以改变的.主要是通过形参中的*arg和**arg来实现的,使用可变参数必须遵守下面规则: 1.位置参数必须出现在这*arg参 ...
- Ubuntu 16.04下Shell脚本中使用数组提示:Syntax error: "(" unexpected
说明:这种现象在CentOS中不会出现. 分析: 可以看出sh指向了dash 解决方式: 1.不要用sh执行,使用./test.sh执行.或者bash执行. 2.根治,直接修改sh的指向,改成bash ...
- 安装CentOS 6停在selinux-policy-targeted卡住的问题解决
在刚开始安装时,设置swap分区.设置swap分区.设置swap分区 参考: http://tieba.baidu.com/p/3817971339 http://blog.csdn.net/zhan ...
- 【java】服务器端获取用户访问的URL/用户IP/PC还是移动端
@RequestMapping(value="/test") @ResponseBody public void test1(HttpServletRequest request, ...
- javascript的rsa加密和python的rsa解密
先说下目前测试情况:javascript加密后的数据,python无法完成解密,我估计是两者的加密解密方法不同 1.看了这篇文章:http://blog.nsfocus.net/python-js-e ...
- 基于CentOS与VmwareStation10搭建Oracle11G RAC 64集群环境:3.安装Oracle RAC-3.6.集群管理命令
3.6. 集群管理命令 3.6.1. RAC的启动与关闭 oracle rac默认会开机自启动,如需维护时可使用以下命令: 关闭: crsctl stop cluster 停止本节点集群服务 crsc ...
- JS使用cookie实现DIV提示框只显示一次的方法
本文实例讲述了JS使用cookie实现DIV提示框只显示一次的方法.分享给大家供大家参考,具体如下: 这里运用JavaScript的cookie技术,控制网页上的提示DIV只显示一次,也就是当用户是第 ...
- BUPT复试专题—解析表达式(2015)
题目描述 输入一个字符串形式的表达式,该表达式中包括整数,四则运算符(+.-.*./),括号,三角函数(sin(x).cos(x).tan(x)),底数函数(lg(x).ln(x)),计算该表达式的值 ...