博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
in 和 exists的区别
阅读量:4992 次
发布时间:2019-06-12

本文共 1843 字,大约阅读时间需要 6 分钟。

 表展示

    首先,查询中涉及到的两个表,一个user和一个order表,具体表的内容如下:

    user表:

    

    order表:

    

 

  in

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

    具体sql语句如下:

1 SELECT 2     * 3 FROM 4     `user` 5 WHERE 6     `user`.id IN ( 7         SELECT 8             `order`.user_id 9         FROM10             `order`11     )

    这条语句很简单,通过子查询查到的user_id 的数据,去匹配user表中的id然后得到结果。该语句执行结果如下:

    

    它的执行流程是什么样子的呢?让我们一起来看一下。

    首先,在数据库内部,查询子查询,执行如下代码:

SELECT            `order`.user_id        FROM            `order`

    执行完毕后,得到结果如下:

    

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

    

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

    

  exists

    指定一个子查询,检测行的存在。遍历循环外表,然后看外表中的记录有没有和内表的数据一样的。匹配上就将结果放入结果集中。

    具体sql语句如下:

1 SELECT 2     `user`.* 3 FROM 4     `user` 5 WHERE 6     EXISTS ( 7         SELECT 8             `order`.user_id 9         FROM10             `order`11         WHERE12             `user`.id = `order`.user_id13     )

    这条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效率高的说法是不准确的。

转载于:https://www.cnblogs.com/xuyufengme/p/9175928.html

你可能感兴趣的文章
eclipse 僵死/假死 问题排查及解决
查看>>
番茄时间
查看>>
四位计算机的原理及其实现【转】
查看>>
mediawiki简易安装文档
查看>>
Ubuntu server 命令备忘
查看>>
yum常用操作
查看>>
MES系统框架及MES开源框架|C/S框架网软著产品
查看>>
以boost::function和boost:bind取代虚函数
查看>>
linux 下启动SVN服务
查看>>
vue框架学习
查看>>
现代计算机接口实验 (三)8255实验
查看>>
spring——获取ClassLoader
查看>>
javascript函数
查看>>
luogu4093 序列 (cdq分治优化dp)
查看>>
BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )
查看>>
从零开始学算法(一)
查看>>
d3d 纹理坐标1:1对应到屏幕坐标.
查看>>
SQL Server优化器特性-隐式谓词
查看>>
国内不谈Java--硅谷有感
查看>>
hdu3371
查看>>