美文网首页数据库MySql
sql中in、exists、not in、not exists的

sql中in、exists、not in、not exists的

作者: 5e30faa7d323 | 来源:发表于2017-08-30 17:42 被阅读45次

    exists和in的含义

    • exists的理解

    exists对主表用loop逐条查询,每次查询都会查看exists的条件语句,当 exists里的条件语句能够返回记录行时(无论记录行是的多少,只要能返回),条件就为真,返回当前loop到的这条记录,反之如果exists里的条 件语句不能返回记录行,则当前loop到的这条记录被丢弃,exists的条件就像一个bool条件,当能返回结果集则为true,不能返回结果集则为 false。

    • in的理解

    mysql中的in语句是把主表和子表作hash 连接。in会使用子查询字段去到主表匹配需要的行。

    • 具体的例子
      select * from user where exists (select 1);

    对user表的记录逐条取出,由于子条件中的select 1永远能返回记录行,那么user表的所有记录都将被加入结果集,所以与select * from user;是一样的
    又如下
    select * from user where exists (select * from user where userId = 0);
    可以知道对user表进行loop时,检查条件语句(select * from user where userId = 0),由于userId永远不为0,所以条件语句永远返回空集,条件永远为false,那么user表的所有记录都将被丢弃。not exists与exists相反,也就是当exists条件有结果集返回时,loop到的记录将被丢弃,否则将loop到的记录加入结果集。
    总的来说,如果A表有n条记录,那么exists查询就是将这n条记录逐条取出,然后判断n遍exists条件 ,in查询相当于多个or条件的叠加,这个比较好理解,比如下面的查询
    select * from user where userId in (1, 2, 3);
    等效于
    select * from user where userId = 1 or userId = 2 or userId = 3;
    not in与in相反,如下
    select * from user where userId not in (1, 2, 3);
    等效于
    select * from user where userId != 1 and userId != 2 and userId != 3;
    总的来说,in查询就是先将子查询条件的记录全都查出来,假设结果集为B,共有m条记录,然后在将子查询条件的结果集分解成m个,再进行m次查询,值得一提的是,in查询的子条件返回结果必须只有一个字段,例如
    select * from user where userId in (select id from B);
    而不能是
    select * from user where userId in (select id, age from B);
    而exists就没有这个限制。

    exists和in的性能

    如果查询的两个表大小相当,那么用in和exists差别不大。
    如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:
    例如:表A(小表),表B(大表)

    • 例子1:
    select * from A where cc in (select cc from B) 效率低,用到了A表上cc列的索引;
    select * from A where exists(select cc from B where cc=A.cc) 效率高,用到了B表上cc列的索引。 
    

    相反的

    • 例子2:
    select * from B where cc in (select cc from A) 效率高,用到了B表上cc列的索引;
     
    select * from B where exists(select cc from A where cc=B.cc) 效率低,用到了A表上cc列的索引。
    

    not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。
    in 与 =的区别
    select name from student where name in ('zhang','wang','li','zhao');

    select name from student where name='zhang' or name='li' or name='wang' or name='zhao'的结果是相同的。

    • 知乎上网友的理解

    in会使用你的子查询字段去到主表匹配你需要的行,而exists是根据匹配项去判断是或者否,然后根据是否决定结果,子查询的表大,用exists判断,效率就会高,而当子查询很小的时候,直接匹配你需要的值则更快。比如主表4万行,子查询里面有5条数据,那么exists会把4万行在子查询里面进行匹配,匹配上了就显示,匹配不上就不显示,所以需要判断4万次,而in则会在主表4万行里面去检索这5条记录,由于索引等等的存在,in的效率通常会更高,但是如果反过来,主表5条记录,子查询里面有4万行,exists只进行5次判断,而in会用4万个数据去匹配这5条记录,当然exists更快。

    相关文章

      网友评论

        本文标题:sql中in、exists、not in、not exists的

        本文链接:https://www.haomeiwen.com/subject/jqdxjxtx.html