plsql exist和in 的区别

<![endif]--> <![endif]-->

发现公司同事很喜欢用exists 和in 做子查询关联,我觉得很有必要研究下

两者的区别,供参考和备忘

/* (这段信息来自网络begin )对于in 的使用,就相当于对inner table 执行一个带distinct 的子查询,然后将得到的结果集再和outer table 进行外连接,连接方式和索引使用任然同于普通两表的连接(这段信息来自网络end )*/

对于网络的这段描述,我给予了测试,测试表为 liomuser.staff ,和liomuser.department ,这两张表都是小表,数量在1 万左右。

-- 例如:

select *

from liomuser.staff

where department_id in ( select department_id from liomuser.department);

-- 可以转换为

select a.*

from liomuser.staff a,

( select distinct department_id from liomuser.department) b

where a.department_id = b.department_id;

执行计划分别如下:

( 1 ) select *

from liomuser.staff

where department_id in ( select department_id from liomuser.department);

( 2 ) select a.*

from liomuser.staff a,

( select distinct department_id from liomuser.department) b

where a.department_id = b.department_id;

我选择的是两个小表,从数据上看采用外连接的方式除了一致性读要稍微小一点,两者执行计划和统计信息几乎一样。

测试结果显示对于小表网络上给出的描述是正确的

但是以我的经验,in 的方式应该比外连接性能要差很多,按照上面的测试,两者似乎是一样的执行路径,是不是应为表数据量少的缘故呢?

我决定采用两张大表做测试,cust_order 和order_detail 这两张表的数据量都在一千万以上。

首先测试in ,语句如下:

select a.*

from liomuser.cust_order a

where order_id in ( select order_id from liomuser.order_detail b);

执行计划如下:

测试2 外连接,语句如下:

select a.*

from liomuser.cust_order a,

( select distinct order_id from liomuser.order_detail) b

where a.order_id = .order_id ;

执行计划如下:

对着两个大表的in 和外连接的对比可以看出,采用外连接的执行计划明显优于in 的方式,采用in方式则表连接采用nested loop 方式,而外连接采用了HASH JOIN ,

并且in 方式的CPUcost 要比外连接大1/3, 这样看来,对于小表,或者说inner table 是小表的查询,in 和外连接都差不多,但是对于大表,特别是inner table 数据量巨大的时候,采用外连接要好很多。

由此看出,in 并不完全等同于与inner table 做distinct 外连接,但是外连接要比in 有效率得多。

下面讨论下 EXIST

实际上exists 等同于先对outer table 进行扫描,从中检索到每行和inner table 做循环匹配,执行计划如下:

注释:部分网上资料认为exists 对outer table 会进行全表扫描,但是在该执行计划中没有发现全表扫描,仍然走了索引。

Exists 的写法可以转换成:

declare cnt number ( 10 );

for cur in ( select a.*  from liomuser.cust_order a) loop

cnt:= 0 ;

select count ( 1 ) into cnt from liomuser.order_detail where order_id=cur.order_id;

if cnt<> 0 then

return cur;

end if ;

end loop ;

exists 与 in 的比对:

语句 1 , in

语句 2 , exsits

从执行计划上来看没有任何区别,再让我们看看执行的统计信息:

语句 1 , in

select a.*

from liomuser.cust_order a

where order_id in ( select order_id from liomuser.order_detail b)

语句 2 , exists

select a.*

from liomuser.cust_order a

where exists

( select 1 from liomuser.order_detail b where a.order_id = b.order_id)

从两种方式统计信息可以看出,采用 exists 的一致性读要比 in 要好,但是 bytessent 要比 in高,这个也从侧面验证了前面所说的 exists 相当于 loop

 

通过上面解释现在很容易明白当 inner table 数据量巨大且索引情况不好 ( 大量重复值等 ) 则不宜使用产生对 inner table 检索而导致系统开支巨大 IN 操作,建议对 innertable 过大的查询,采取 exsits ,或者外连接方式

另外: NOT IN 子句将执行个内部排序和合并 . 无论在哪种情况下 ,NOT IN 都是

最低效 ( 它对子查询中表执行了个全表遍历 ). 为了避免使用 NOT IN , 我们可以把它改写成外连接 (Outer Joins) 或 NOT EXISTS

时间: 2024-10-22 16:01:36

plsql exist和in 的区别的相关文章

php面试题汇总四(基础篇附答案)

1. 什么事面向对象?主要特征是什么? 面向对象是程序的一种设计方式,它利于提高程序的重用性,使程序结构更加清晰.主要特征:封装.继承.多态. 2. SESSION 与 COOKIE的区别是什么,请从协议,产生的原因与作用说明? 1.http无状态协议,不能区分用户是否是从同一个网站上来的,同一个用户请求不同的页面不能看做是同一个用户. 2.SESSION存储在服务器端,COOKIE保存在客户端.Session比较安全,cookie用某些手段可以修改,不安全.Session依赖于cookie进行

关于sql的一部分知识

用sql创建用户数据库这部分不讲了,因为我都是通过可视化界面的因为没什么技术含量(可能是没遇到过,不足之处请大牛补充).我这里都是用sql语句的非可视化界面 文章中使用的exp是例子的意思. 1.sql的数据类型有: 字符数据: char(n),  varchar(n),  text 二进制数据:binary(n), varbinary(n), image                              整数数据:int,  smallint,  tinyint,  bit 4字节  

安装64位的oracle数据库, 使用自带的sqldeveloper

个人感觉这个东西比plsql要好用, 虽然界面有点丑, 整个使用与plsql也没多大区别, 这里是他的位置C:\oracle_11g\product\11.2.0\dbhome_1\sqldeveloper\sqldeveloper.exe 整个打开的界面是这个样子的 不过这个东西在使用之前需要指定一下jdk的位置, 而且还有点奇怪, 只能使用32位的1.6的jdk, 指定好位置之后就可以进去了, 首先先建立一个连接, 就是与数据库里面用户的连接, 右键点击新建 然后输入一个连接名和用户名密码就

邓_php面试【003】——完整版

php面试题汇总四(基础篇附答案) 1. 什么事面向对象?主要特征是什么? 面向对象是程序的一种设计方式,它利于提高程序的重用性,使程序结构更加清晰.主要特征:封装.继承.多态. 2. SESSION 与 COOKIE的区别是什么,请从协议,产生的原因与作用说明? 1.http无状态协议,不能区分用户是否是从同一个网站上来的,同一个用户请求不同的页面不能看做是同一个用户. 2.SESSION存储在服务器端,COOKIE保存在客户端.Session比较安全,cookie用某些手段可以修改,不安全.

PostgreSQL的架构

是最先进的数据库.他的第一个版本在1989年发布,从那时开始,他得到了很多扩展.根据db-enginers上的排名情况,PostgreSQL目前在数据库领域排名第四. 本篇博客,我们来讨论一下PostgreSQL的内部架构,以及各个组件之间如何交互.这将是本期PostgreSQL DBA系列博客的基石. 一.PostgreSQL的架构 PostgreSQL的物理架构非常简单,它由共享内存.一系列后台进程和数据文件组成. (如下图) 二.Shared Memory 共享内存是服务器服务器为数据库缓

2020最新PHP面试题(附带答案)

1. 什么事面向对象?主要特征是什么? 面向对象是程序的一种设计方式,它利于提高程序的重用性,使程序结构更加清晰.主要特征:封装.继承.多态. 更多学习内容请访问: 怎么从一名码农成为架构师的必看知识点:目录大全(不定期更新) 2. SESSION 与 COOKIE的区别是什么,请从协议,产生的原因与作用说明? 1.http无状态协议,不能区分用户是否是从同一个网站上来的,同一个用户请求不同的页面不能看做是同一个用户. 2.SESSION存储在服务器端,COOKIE保存在客户端.Session比

oracle在SQLPLUS 和PLSQL建 job 的区别

oracle在SQLPLUS 和PLSQL建 job 的区别 Java代码   //建立job variable test_job_really number; begin dbms_job.submit(:test_job_really,'test_jobproce;',sysdate,'sysdate+1/1440'); commit; end; -------------------------- 如果是PLSQL的话 --declare declare test_job_really n

PLSQL中显示Cursor、隐示Cursor、动态Ref Cursor区别

一.显式cursor 显式是相对与隐式cursor而言的,就是有一个明确的声明的cursor.显式游标的声明类似如下(详细的语法参加plsql ref doc ): cursor cursor_name (parameter list) is select ... 游标从declare.open.fetch.close是一个完整的生命旅程.当然了一个这样的游标是可以被多次open进行使用的,显式cursor是静态cursor,她的作用域是全局的,但也必须明白,静态cursor也只有pl/sql代

SQL、T-SQL与PL-SQL的区别

SQL是Structrued Query Language的缩写,即结构化查询语言.它是负责与ANSI(美国国家标准学会)维护的数据库交互的标准.作为关系数据库的标准语言,它已被众多商用DBMS产品所采用,使得它已成为关系数据库领域中一个主流语言,不仅包含数据查询功能,还包括插入.删除.更新和数据定义功能. T-SQL 即 Transact-SQL,是 SQL 在 Microsoft SQL Server 上的增强版,它是用来让应用程式与 SQL Server 沟通的主要语言.T-SQL 提供标