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 的区别的更多相关文章

  1. 你真的会玩SQL吗?EXISTS和IN之间的区别

    你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...

  2. 转【】浅谈sql中的in与not in,exists与not exists的区别_

    浅谈sql中的in与not in,exists与not exists的区别   1.in和exists in是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表 ...

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

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

  4. in和exists的区别与SQL执行效率

    in和exists的区别与SQL执行效率最近很多论坛又开始讨论in和exists的区别与SQL执行效率的问题,本文特整理一些in和exists的区别与SQL执行效率分析 SQL中in可以分为三类: 1 ...

  5. in和exists的区别与SQL执行效率分析

    可总结为:当子查询表比主查询表大时,用Exists:当子查询表比主查询表小时,用in SQL中in可以分为三类: 1.形如select * from t1 where f1 in ('a','b'), ...

  6. 面试被问之-----sql优化中in与exists的区别

    曾经一次去面试,被问及in与exists的区别,记得当时是这么回答的:''in后面接子查询或者(xx,xx,xx,,,),exists后面需要一个true或者false的结果",当然这么说也 ...

  7. SQL in、not in、exists和not exists的区别:

    来自:http://blog.sina.com.cn/s/blog_8a0c4f130100zaw2.html 先谈谈in和exists的区别: exists:存在,后面一般都是子查询,当子查询返回行 ...

  8. Sql语句中IN和exists的区别及应用

    表展示 首先,查询中涉及到的两个表,一个user和一个order表,具体表的内容如下: user表: order表: in 确定给定的值是否与子查询或列表中的值相匹配.in在查询的时候,首先查询子查询 ...

  9. Sql 语句中 IN 和 EXISTS 的区别

    IN 语句:只执行一次 确定给定的值是否与子查询或列表中的值相匹配.in在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选.所以相对内表比较小的时候,in的速度较快 ...

随机推荐

  1. java读写文件及保留指定位小数

    1)先上代码: public static void main(String[] args)throws IOException{ double[][] B=new double[1043][2102 ...

  2. xcode编译项目Permission denied错误

    打开终端,输入命令     sudo chmod -R 777 工作目录

  3. 使用.reg文件删除暴风影视库图标和注册信息

    暴风播放器安装后会自动安装一个叫暴风影音库的软件,在你的电脑资源管理器中增加了一个“暴风影视库”的图标.看着很烦,删起来还比较麻烦,于是搜索了相关资源,自己写了个注册表处理文件,方便大家一键删除之. ...

  4. fl2440hello world模块驱动编写

    许多语言,例如C,C++,JAVA等等都是从hello world开始的,因此我们的驱动程序的开发也要从hello world入手. 首先来看下我们的代码: /******************** ...

  5. Mybatis c3p0 整合

    1.下载c3p0 2.实现 UnpooledDataSourceFactory package com.joinhealth.esb.db; import org.apache.ibatis.data ...

  6. Druid和Spark对比

    Druid和Spark对比 不是Spark专家, 如果描绘有错误, 请通过邮件列表或者其他方式告知我们 Spark实现弹性的分布式数据集概念的计算集群系统, 可以看做商业分析平台. RDDs能复用持久 ...

  7. hadoop2.2.0伪分布式安装

    修改主机名和IP的映射关系 vi /etc/hosts 192.168.61.134 hadoop 关闭防火墙 #查看防火墙状态 service iptables status #关闭防火墙 serv ...

  8. python合并多个csv文件并去重

    #coding=utf-8 import os import pandas as pd import glob def hebing(): csv_list = glob.glob('*.csv') ...

  9. web应用程序指识别中的指纹收集

    web应用程序指纹识别是入侵前的关键步骤,假设通过指纹识别能确定web应用程序的名称及版本号.下一步就可以在网上搜索已公开的漏洞.或网上搜到其源码然后进行白盒的漏洞挖掘. 指纹识别的核心原理是通过正則 ...

  10. 菜鸟调错(五)——jetty执行时无法保存文件

    背景交代: 上一篇博客写的是用jetty和Maven做开发.測试.在使用的过程中遇到一个小问题.就是在jetty启动以后,改动了jsp.xml等文件无法保存. 错误信息: 解决方式: 到Maven库( ...