PHP群:95885625 Hbuilder+MUI群:81989597 站长QQ:634381967
    您现在的位置: 首页 > 数据库 > SQL Server教程 > 正文

    SQL Server查询in和exists的区别

    作者:admin来源:网络浏览:时间:2020-09-30 00:07:50我要评论
    导读:in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。一、in的语法test_expression [ NOT ] ...
    in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。

     
    一、in的语法

    test_expression [ NOT ] IN

    subquery
    | expression [ ,...n ]
    )


    参数

    test_expression

    是任何有效的 Microsoft® SQL Server™ 表达式。

    subquery

    是包含某列结果集的子查询。该列必须与 test_expression 有相同的数据类型。

    expression [,...n]

    一个表达式列表,用来测试是否匹配。所有的表达式必须和 test_expression 具有相同的类型。
     

    结果类型

    布尔型
     

    结果值

    如果 test_expression 与 subquery 返回的任何值相等,或与逗号分隔的列表中的任何 expression 相等,那么结果值就为 TRUE。否则,结果值为 FALSE。

     
    二、EXISTS
     

    EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False

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

    语法: EXISTS subquery


    参数: subquery 是一个受限的 SELECT 语句 (不允许有 COMPUTE 子句和 INTO 关键字)。


    结果类型: Boolean 如果子查询包含行,则返回 TRUE ,否则返回 FLASE 。
     

    三、IN 与 EXISTS 的区别

    IN

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

    EXISTS

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


    分别适用在什么情况?

    以子查询 ( select y from T2 )为考虑方向
     

    如果子查询的结果集很大需要消耗很多时间,但是T1比较小执行( select null from t2 where y = x.x )非常快,那么exists就比较适合用在这里


    相对应得子查询的结果集比较小的时候就应该使用in.
     

    性能的比较
     

    如果查询的两个表大小相当,那么用in和exists差别不大。

    如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:

     

    例如
    select * from A where id in (select id from B);

    select * from A where exists (select 1 from B where A.id=B.id);

    对于以上两种情况,in是在内存里遍历比较,而exists需要查询数据库,所以当B表数据量较大时,exists效率优于in。

    1、select * from A where id in (select id from B);

    in()只执行一次,它查出B表中的所有id字段并缓存起来。之后,检查A表的id是否与B表中的id相等,如果相等则将A表的记录加入结果集中,直到遍历完A表的所有记录。
    它的查询过程类似于以下过程:

    代码如下:
    List resultSet={};
    Array A=(select * from A);
    Array B=(select id from B);

    for(int i=0;i<A.length;i++) {
       for(int j=0;j<B.length;j++) {
          if(A[i].id==B[j].id) {
             resultSet.add(A[i]);
             break;
          }
       }
    }
    return resultSet;


    可以看出,当B表数据较大时不适合使用in(),因为它会B表数据全部遍历一次
    如:A表有10000条记录,B表有1000000条记录,那么最多有可能遍历10000*1000000次,效率很差。
    再如:A表有10000条记录,B表有100条记录,那么最多有可能遍历10000*100次,遍历次数大大减少,效率大大提升。

    结论:in()适合B表比A表数据小的情况www.111cn.net

    2、select * from A where exists (select 1 from B where A.id=B.id);

    exists()会执行A.length次,它并不缓存exists()结果集,因为exists()结果集的内容并不重要,重要的是其内查询语句的结果集空或者非空,空则返回false,非空则返回true。
    它的查询过程类似于以下过程:

    代码如下:
    List resultSet={};
    Array A=(select * from A);

    for(int i=0;i<A.length;i++) {
       if(exists(A[i].id) {  //执行select 1 from B where B.id=A.id是否有记录返回
           resultSet.add(A[i]);
       }
    }
    return resultSet;


    当B表比A表数据大时适合使用exists(),因为它没有那么多遍历操作,只需要再执行一次查询就行。
    如:A表有10000条记录,B表有1000000条记录,那么exists()会执行10000次去判断A表中的id是否与B表中的id相等。
    如:A表有10000条记录,B表有100000000条记录,那么exists()还是执行10000次,因为它只执行A.length次,可见B表数据越多,越适合exists()发挥效果。
    再如:A表有10000条记录,B表有100条记录,那么exists()还是执行10000次,还不如使用in()遍历10000*100次,因为in()是在内存里遍历比较,而exists()需要查询数据库,我们都知道查询数据库所消耗的性能更高,而内存比较很快。

    结论:exists()适合B表比A表数据大的情况

    当A表数据与B表数据一样大时,in与exists效率差不多,可任选一个使用。
    在插入记录前,需要检查这条记录是否已经存在,只有当记录不存在时才执行插入操作,可以通过使用 EXISTS 条件句防止插入重复记录。
    insert into A (name,age) select name,age from B where not exists (select 1 from A where A.id=B.id);

    EXISTS与IN的使用效率的问题,通常情况下采用exists要比in效率高,因为IN不走索引。但要看实际情况具体使用:IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。

    not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。

    转载请注明(B5教程网)原文链接:https://b5.mxunkeji.com/content-36-550-1.html
    相关热词搜索: exists SQL Server