• SQL语句——exists和in区别


    表结构及数据

    user表

    order表

    in

    select * from table A where id in (xxxxxxxxxxx):满足条件的数据会被查出来;

    先查询子查询的表,然后将内表、外表做一个笛卡尔积,然后按条件进行筛选。所以相对内表较小的时候,in的速度比较快;

    SELECT
        m.*
    FROM
        user m
    WHERE
        m.id IN
        (
            SELECT
                user_id
            FROM
                order n )

    这条语句通过子查询到order表的user_id的数据,去匹配user表的id,结果如下

    执行流程如下:

    1)在数据库内部执行子查询

     SELECT
                user_id
            FROM
                order n

    执行结果

    2)将子查询结果和user表做笛卡尔积,结果如下:

    3)再根据我们的条件:m.id IN order.user_id,将结果进行筛选(即比较id列和user_id列值是否相等,不相等的删除)

    4)得到符合条件的数据

    exists

    select * from table B where exists (xxxxxxxxxxx):满足不满足都会查出来

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

    SELECT
        user.*
    FROM
        user
    WHERE
        EXISTS (
            SELECT
                order.user_id
            FROM
                order
            WHERE
                user.id = order.user_id
        )

    这条sql执行结果和上面的in结果一样。

    但是,执行流程不一样:

    使用exists关键字进行查询时候,首先查询的不是子查询,而是查询主表,也就是说,我们先执行的sql语句是:

    SELECTuser.*FROMuser

    得到结果:

    然后,根据表的每一条记录,执行以下语句,一次去判断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要快。

    作者:howtosay
             
    放牛娃的个人笔记整理,每天记录一点点,进步一点点
  • 相关阅读:
    软件的安全性应从哪几个方面去测试?
    目前主要的测试用例设计方法是什么?
    什么是软件质量?
    软件配置管理的作用?软件配置包括什么?
    什么是软件测试?软件测试的目的与原则
    软件生存周期及其模型是什么?
    软件的概念和特点?软件复用的含义?构件包括哪些?
    一台客户端有三百个客户与三百个客户端有三百个客户对服务器施压,有什么区别?
    在搜索引擎中输入汉字就可以解析到对应的域名,请问如何用LoadRunner进行测试。
    测试08
  • 原文地址:https://www.cnblogs.com/hongzm/p/9172529.html
Copyright © 2020-2023  润新知