无论是做项目还是普通使用SQL,我们通常都会使用IN。因为很好理解,也很方便。但是,面对着多层查询嵌套,或者IN关键字里面的结果集数量巨大,查询的效率就会直线下降。这时候,我们应该用好EXSITS。

首先,来一个简单的例子。

with score(id,name,subject,score)
as(
select 0,'张三','数学',88 from dual union all
select 1,'张三','英语',78 from dual union all
select 2,'李四','数学',68 from dual union all
select 3,'李四','英语',98 from dual union all
select 4,'王五','数学',77 from dual union all
select 5,'王五','英语',92 from dual union all
select 6,'赵六','数学',81 from dual union all
select 7,'赵六','英语',75 from dual
)
,has_phone(name,has_phone)
as(
select '张三','有' from dual union all
select '李四','没有' from dual union all
select '王五','没有' from dual union all
select '赵六','有' from dual
)
--select *
-- from score a
-- where name in (select name from has_phone where has_phone = '有')
select *
from score a
where exists (select 1
from has_phone b
where b.name = a.name
and has_phone = '有')

  这段SQL的意思是,查询有手机的同学的成绩。

那么我来理解一下IN和EXSITS的区别吧。 
在使用IN的时候。 
数据库首先是去在has_phone里面查找所有条件为“有”的name。 
然后把这些结果集让每一个name去匹配。

在使用EXSITS的时候。 
数据库是先查询SCORE,然后每个连接条件到EXSITS里面进行判断。 
如果为TRUE,则加入结果集,否则就跳过。

EXSITS执行过程 
可以理解为: 
for x in (select * from score a) 
loop

if(exists(select 1 from has_phone b where b.name = a.name )) 
then 
  output the record; 
end if;

end loop;

对于in 和 exists的性能区别: 
如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用in; 
反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用exists. 
其实我们区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists, 
那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询,所以我们会以驱动表的快速返回为目标, 
那么就会考虑到索引及结果集的关系了

原文:http://dacoolbaby.iteye.com/blog/1638990

EXSITS应该怎么用?的更多相关文章

  1. sql中的exsits和not exsits

    select * from table where exsits(sql语句) :  括号中sql语句有数据则返回这些相关id的数据集 select * from table where not ex ...

  2. .NET Core的文件系统[3]:由PhysicalFileProvider构建的物理文件系统

    ASP.NET Core应用中使用得最多的还是具体的物理文件,比如配置文件.View文件以及网页上的静态文件,物理文件系统的抽象通过PhysicalFileProvider这个FileProvider ...

  3. CentOS一键ftp

    # Version : 1.0 # Author : 果子 # Date : -- :: # Description : 只需要三步即可完成安装 # chmod a+x install_vsftpd. ...

  4. SQL Server null知多少?

    null是什么? 不知道.我是说,他的意思就是不知道(unknown). 它和true.false组成谓词的三个逻辑值,代表“未知”.与true和false相比,null最难以令人捉摸,因为它没有明确 ...

  5. iOS 简单的分段下载文件

    首先自己写个请求数据的类 首先.h文件 #import <Foundation/Foundation.h> @interface Downloaders : NSObject<NSU ...

  6. DB

    数据库(DB):1:降低存储数据的冗余度.2:更高的数据一致性.3:存储的数据可以共享.4:可以建立数据库所遵循的标准. 关系型数据库(RDBMS):基本单位就是表.一张表就是一个实体.MYSQL语句 ...

  7. 分析sql语句所有表名及其别名的正则表达式

    最近为了 写一个分布式的数据组件构想了很多的方案,最近一个简单易行的方案终于在脑袋里成型.昨晚想到凌晨1点多,发现方案虽简单,但所有的数据库工具就不能使用了 .除非自己写一下查询分析器来执行程序员自己 ...

  8. 代码创建数据库_表--SqlServer数据库

    /*1.创建数据库的时候需要设置的基本属性: 数据库名称 逻辑名称 初始大小 文件增长 路径*/ --语法: -- create database 数据库名称 -- on [primary]--创建数 ...

  9. 利用注解进行sql反射代码示例

    @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface Table { String val ...

随机推荐

  1. 谈谈对MVC、MVP和MVVM的理解

    刚出来工作的时候维护过一个老系统,该系统是用微软的ASP(Active Server Pages 动态服务器页面)写的.每一个页面都是一个ASP文件,每一个一个ASP文件中又同时包含了HTML.CSS ...

  2. Ajax实现异步上传图片

    要求:点击页面浏览按钮后,选择需要上传的图片,页面无刷新,将上传的图片展示出来 开发流程 一:在页面编写表单代码和js代码 <!DOCTYPE html PUBLIC "-//W3C/ ...

  3. Log4J是Apache组织的开源一个开源项目,通过Log4J,可以指定日志信息输出的目的地,如console、file等。Log4J采用日志级别机制,请按照输出级别由低到高的顺序写出日志输出级别。

    Log4J是Apache组织的开源一个开源项目,通过Log4J,可以指定日志信息输出的目的地,如console.file等.Log4J采用日志级别机制,请按照输出级别由低到高的顺序写出日志输出级别. ...

  4. ubuntu 安装 avahi服务

    sudo apt-get install avahi-daemon sudo apt-get install avahi-utils

  5. windows 中 Eclipse 打开当前文件所在文件夹

    默认情况下使用eclipse打开当前文件所在文件夹很麻烦,需要右键点击 Package Explorer 中的节点选择属性,然后复制路径,再打开资源管理器,然后再把路径粘贴进去.而MyEclipse一 ...

  6. 2534: Uva10829L-gap字符串

    2534: Uva10829L-gap字符串 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 177  Solved: 66[Submit][Statu ...

  7. java读取项目资源文件的方法

    1.把资源文件放在项目的Resource文件夹下,并使其设置成为资源文件夹(通过idea或者eclise)2. Thread.currentThread().getContextClassLoader ...

  8. fnt 图字原理

    摘自:http://blog.csdn.net/wzq9706/article/details/8188256 首先要介绍一下,图字是怎么来的?其实这个很早很早了,记得80后在95年开始玩DOS下的仙 ...

  9. Android异步处理之AsyncTaskLoader简单使用

    简介 不管是在Android应用开发还是Android平台开发中,异步处理通常是最基本的coding要求.如果你还在主线程中写一些数据库,网络请求,读写本地文件等操作的话那说明你还不是一个合格的And ...

  10. spring + quartz 定时

    springConfig配置文件: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=& ...