zoukankan      html  css  js  c++  java
  • SQL中如何使用EXISTS替代IN

    原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/6385312.html

      我们在程序中一般在做SQL优化的时候讲究使用EXISTS带替代IN的做法,理由是EXISTS执行效率要比IN高。
      之前我一直挺懵懂的一件事情是如何使用EXISTS来替换IN呢,二者表示的意义又是什么呢?今天就我个人理解记录一下
      IN表示范围,指某一字段在某一范围之内,这个范围一般使用子查询来获取,由此可知IN子查询返回的结果应该就是这个范围集。
      EXISTS表示存在,指至少存在一处,这个条件由EXISTS子查询来完成,但是在这里EXISTS子查询返回的结果却不再是一个结果集,而是一个布尔值(true或false),其实这个挺好理解的,EXISTS就表示如果子查询能查到值则返回true,则执行EXISTS之前的语句。
    举个栗子
      假如有一个表user,它有两个字段id和name,我们要查询名字中带a的用户信息:
      最简单的SQL:select * from user where name like '%a%';
      使用IN的SQL:select u.* from user u where u.id in (select uu.id from user uu where uu.name like '%a%');
      我们现在将使用IN的SQL修改为使用EXISTS的SQL该怎么写呢?
      一开始我直接将u.id in 替换为EXISTS,获得如下语句 :
        select u.* from user u where exists(select uu.id from user uu where uu.name like '%a%');
      经过测试发现输出结果错误,该语句将所有的用户全部一个不漏的查询出来了,相信你也发现了问题,后来我对上述语句做了修改如下:
        select u.* from user u where exists (select uu.id from user uu where uu.name like '%a%' and uu.id=u.id);
      如你所见,只是在子查询中添加了“and uu.id=u.id”,结果查询结果正确。
      那么原因为何呢?
      总结:EXISTS子查询可以看成是一个独立的查询系统,只为了获取真假逻辑值,EXISTS子查询与外查询查询的表是两个完全独立的毫无关系的表(当第二个表中的name中有包含a的姓名存在,那么就执行在第一个表中查询所有用户的操作),当我们在子查询中添加了id关联之后,EXISTS子查询与外查询查询的表就统一了,是二者组合组建的虚表,是同一个表(这样当子查询查询到虚表中当前行的uu.name中包含a时,则将虚表当前行中对应的u.id与u.name查询到了)
      所以一切的重点就在这个ID关联之上,添加ID关联,数据库会先将两张表通过ID关联组合成一张虚表,所有的查询操作都在这张虚表上完成,操作的是同一张表,当然就不会出现之前的那种情况了!

  • 相关阅读:
    事务
    XML小总结
    java中array,arrayList,iterator;
    MariaDB Galera Cluster 部署(如何快速部署 MariaDB 集群)
    RHCE7认证学习笔记17——KickStart安装系统
    CentOS中安装MySQL数据库
    centos下搭建svn服务器端/客户端
    AWS安装CDH5.3-CentOS6.4中关键操作步骤
    AWS安装CDH5.3-CentOS6.4
    [转]Servlet 工作原理解析
  • 原文地址:https://www.cnblogs.com/shujuyr/p/15001355.html
Copyright © 2011-2022 走看看