zoukankan      html  css  js  c++  java
  • SQL中exists和in的用法以及区别

    一、in 用法

    in 语法为:

    select *
    from table_name
    where col_name in (value1, value2,...);
    

    in 操作符允许在 where 子句中规定多个值。

    in 查询相当于多个 or 条件的叠加,比较好理解。

    in 查询就是先将子查询条件的记录全都查出来。

    in 查询的子条件返回结果必须只有一个字段。

    二、exists 用法

    exists 语法为:

    select *
    from table_a a
    where exists (select 1 from table_b b where b.id = b.id);
    

    exists 对外表用 loop 逐条查询,每次查询都会查看 exists 的条件语句。

    exists 里的条件语句能够返回记录行时(无论返回多少记录行,只要能返回),条件就为真,返回当前 loop 到的这条记录。

    反之如果 exists 里的条件语句不能返回记录行,则当前 loop 到的这条记录被丢弃。

    exists 的条件就像一个 bool 条件,当能返回结果集则为 true,不能返回结果集则为 false

    当子查询为 select NULL 时, mysql 仍然认为它是 True

    三、in 与 exists 的区别

    in 语句:只执行一次

    确定给定的值是否与子查询或列表中的值相匹配。

    in 在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选。

    所以相对内表比较小的时候,in 的速度较快。

    exists 语句:执行n次(外表行数)

    指定一个子查询,检测行的存在。

    遍历循环外表,检查外表中的记录有没有和内表的的数据一致的。

    匹配得上就放入结果集。

    区别和应用场景

    inexists 的区别: 如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用 in, 反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用 exists

    其实我们区分 inexists 主要是造成了驱动顺序的改变(这是性能变化的关键),如果是 exists,那么以外层表为驱动表,先被访问,如果是 in ,那么先执行子查询,所以我们会以驱动表的快速返回为目标,那么就会考虑到索引及结果集的关系 ,另外 in 是不对 NULL 进行处理。

    in 是把外表和内表作 hash 连接,而 exists 是对外表作 loop 循环,每次 loop 循环再对内表进行查询。一直以来认为 existsin 效率高的说法是不准确的。

    not in 和 not exists

    如果查询语句使用 not in,那么内外表都进行全表扫描,没有用到索引;

    not exists 的子查询依然能用到表上的索引。所以无论那个表大,用 not exists 都比not in 要快。

    四、结论

    1. 外层查询表小于子查询表,则用 exists,外层查询表大于子查询表,则用 in ,如果外层和子查询表差不多,则爱用哪个用哪个。

    2.not exists 比 not in 效率高。

    in 的遍历是在内存中遍历。

    exists 需要查询数据库。

    查询数据库所消耗的性能更高,而内存比较快。

    参考链接1:在MySQL里,有个和in一样的东东叫做exists,但是它比in更牛叉,你会么?

    参考链接2:浅析MySQL中exists与in的使用 (写的非常好)

    参考链接3:Sql 语句中 IN 和 EXISTS 的区别及应用

  • 相关阅读:
    BZOJ 2588
    BZOJ 3524
    BZOJ 3932
    Bzoj1013--Jsoi2008球形空间产生器
    Codevs1743--反转卡片
    Bzoj1208--Hnoi2004宠物收养所
    Bzoj1112--Poi2008砖块Klo
    后缀自动机学习笔记
    Bzoj1588--Hnoi2002营业额统计
    Bzoj1056--Haoi2008排名系统
  • 原文地址:https://www.cnblogs.com/hider/p/12446035.html
Copyright © 2011-2022 走看看