MINUS,外连接,NOT IN,NOT EXISTS 的效率比较

minus 如何实现不去重效果 minus 默认是有去重效果的,但实际的需求中,我们可能又不需要去重效果,那该怎么办呢 阅读详情

关于 MINUS,外连接,NOT IN,NOT EXISTS 的效率比较,绝对是一个很老很老的话题了.

如果要完成这个需求:"取出一些记录,在表A中,不在表B中", 你会采用哪种方案?为什么会采用这种方案?

我作了一个实验, 发现随着数据库版本的不同,CBO的工作方式也有变化.

本文仅限于一般性的分析, 不涉及internal.

 

一.  概述
首先, 我必须纠正自己的一个"错误认识": MINUS的效率很低.
针对上面提到的需求,采用哪种查询方式,其效率取决于:

1.  两个表的数据量,以及数据分布;
2.  表有没有经过分析;
3.  子查询中是否包含NULL值 (很重要);
4.  是否存在索引;
5.  数据库版本:不同版本的数据库,优化器的工作方式会有差异.
二. 环境
首先测试的数据库的版本是Oracle 9.0.1.5,接下来我会在10G中也测试一下.

两个与优化器工作原理相关的的参数都用的是缺省值.


optimizer_index_caching
 integer
 0
 
optimizer_index_cost_adj
 integer
 100
 


 

表T1,T2,结构相同,但是数据不同.T2可以看成是T1的子集.
表的结构很简单,都取自dba_objects视图
 

create table t1 as select * from dba_objects where rownum<=13000;

 

create table t2 as select * from dba_objects where rownum<=11000;

Create index ix_t2 on t2(object_id);

三. 测试
目标: 我想把T1表中其它的数据也导入到T2表.

方式: 启动SQL TRACE, 再用tkprof对生成的trace文件进行解析.

首先用 NOT IN来执行,

1. 使用 NOT IN
 select count(*) from t1 where object_id not in ( select object_id from t2);

 


call
 count
 cpu
 elapsed
 disk
 query
 current
 rows
 
Parse
 1
 0.00
 0.01
 0
 0
 0
 0
 
Execute
 1
 0.00
 0.00
 0
 0
 0
 0
 
Fetch
 2
 16.84
 18.05
 190
 1153542
 0
 1
 
total
 4
 16.84
 18.06
 190
 1153542
 0
 1
 


 


Rows
 Row Source Operation
 
1
 SORT AGGREGATE
 
2000
 FILTER
 
13000
 TABLE ACCESS FULL T1
 
11000 
 TABLE ACCESS FULL T2
 


结论: 两次全表扫描的代价显然太高了,无疑是效率最低的方案.
2. 使用MINUS
 alter system flush shared_pool;
 alter session set sql_trace=true;
 Select count(*) from
     (select object_id from t1
       minus
      select object_id from t2
     );

alter session set sql_trace=false;

 


call
 count
 Cpu
 elapsed
 disk
 query
 current
 rows
 
Parse
 1
 0.01
 0.00
 0
 2
 0
 0
 
Execute
 1
 0.00
 0.00
 0
 0
 0
 0
 
Fetch
 2
 0.04
 0.03
 0
 356
 0
 1
 
total
 4
 0.05
 0.03
 0
 358
 0
 1
 


 


Rows
 Row Source Operation
 
1
 SORT AGGREGATE
 
2000
 VIEW
 
2000  
 MINUS
 
13000
 SORT UNIQUE
 
13000
 TABLE ACCESS FULL T1
 
11000
 SORT UNIQUE
 
11000
 TABLE ACCESS FULL T2
 


结论: 看上去效率很不错
3. 使用 not exists

 alter system flush shared_pool;
 alter session set sql_trace=true;
 select count(*)
      from t1
     where not exists
      (select null from t2 where t2.object_id = t1.object_id);

alter session set sql_trace=false;

 


call
 count
 Cpu
 elapsed
 disk
 query
 current
 rows
 
Parse
 1
 0.01
 0.00
 0
 2
 0
 0
 
Execute
 1
 0.00
 0.00
 0
 0
 0
 0
 
Fetch
 2
 0.08
 0.21
 24
 26197
 0
 1
 
total
 4
 0.09
 0.21
 24
 26199
 0
 1
 


 


Rows
 Row Source Operation
 
1
 SORT AGGREGATE
 
2000
 FILTER
 
13000
  TABLE ACCESS FULL T1
 
11000
 INDEX RANGE SCAN (object id 108538)
 


结论: 效率比NOT IN 好很多,但是不如MINUS,并且存在物理读.

4. 最后来看看我比较喜欢用的外连接(+)

 alter system flush shared_pool;
 alter session set sql_trace=true;
 select count(*)
      from t1, t2
     where t1.object_id = t2.object_id(+)
      and t2.object_id IS NULL;

alter session set sql_trace=false;

 


call
 count
 Cpu
 elapsed
 disk
 query
 current
 rows
 
Parse
 1
 0.01
 0.00
 0
 2
 0
 0
 
Execute
 1
 0.00
 0.00
 0
 0
 0
 0
 
Fetch
 2
 0.05
 0.05
 0
 13222
 0
 1
 
total
 4
 0.06
 0.05
 0
 13224
 0
 1
 


 


Rows
 Row Source Operation
 
1
 SORT AGGREGATE
 
2000
 FILTER
 
13000
 NESTED LOOPS OUTER
 
13000
 TABLE ACCESS FULL T1
 
11000
 INDEX RANGE SCAN (object id 108538)
 


结论: 比NOT EXISTS的效果好,不如MINUS.从查询计划来看,显然不是一个最优计划.

四. 对表分析后再测试
analyze table t1 compute statistics;

1.     NOT IN

alter system flush shared_pool;
alter session set sql_trace=true;

select count(*)
from t1
where object_id not in (select object_id from t2);

alter session set sql_trace=false;

 


call
 count
 Cpu
 elapsed
 disk
 query
 current
 rows
 
Parse
 1
 0.02
 0.00
 0
 0
 0
 0
 
Execute
 1
 0.00
 0.00
 0
 0
 0
 0
 
Fetch
 2
 16.04
 0.05
 0
 0
 0
 1
 
total
 4
 16.06
 0.05
 0
 0
 0
 1
 


 


Rows
 Row Source Operation
 
1
 SORT AGGREGATE
 
2000
 FILTER
 
13000
 TABLE ACCESS FULL T1
 
11000
 TABLE ACCESS FULL T2
 


结论:与分析前相比,没有任何改变
2.     MINUS

alter system flush shared_pool;
alter session set sql_trace=true;

Select count(*) from
  (select object_id from t1
     minus
   select object_id from t2
  );

alter session set sql_trace=false;

 


call
 count
 Cpu
 elapsed
 disk
 query
 current
 rows
 
Parse
 1
 0.00
 0.00
 0
 76
 0
 0
 
Execute
 1
 0.00
 0.00
 0
 0
 0
 0
 
Fetch
 2
 0.05
 0.04
 0
 356
 0
 1
 
total
 4
 0.05
 0.04
 0
 342
 0
 1
 


 


Rows
 Row Source Operation
 
1
 SORT AGGREGATE
 
2000
 VIEW
 
2000
 MINUS
 
13000
 SORT UNIQUE
 
13000
 TABLE ACCESS FULL T1
 
11000
 SORT UNIQUE
 
11000
 TABLE ACCESS FULL T2
 


结论: 查询计划没有改变, 虽然各项指标有些不同.

3.     使用NOT EXISTS

alter system flush shared_pool;
alter session set sql_trace=true;

select count(*)
 from t1
  where not exists
   (select null from t2 where t2.object_id = t1.object_id);

alter session set sql_trace=false;

 


call
 count
 Cpu
 elapsed
 disk
 query
 current
 rows
 
Parse
 1
 0.01
 0.02
 0
 144
 0
 0
 
Execute
 1
 0.00
 0.00
 0
 0
 0
 0
 
Fetch
 2
 0.08
 0.08
 0
 26197
 0
 1
 
total
 4
 0.09
 0.10
 0
 26341
 0
 1
 


 


Rows
 Row Source Operation
 
1
 SORT AGGREGATE
 
2000
 FILTER
 
13000
 TABLE ACCESS FULL T1
 
11000
 INDEX RANGE SCAN (object id 108538)
 


结论: 查询计划也没有改变.

4.     使用 外连接
alter system flush shared_pool;
alter session set sql_trace=true;

select count(*)
 from t1, t2
  where t1.object_id = t2.object_id(+)
   and t2.object_id IS NULL;

alter session set sql_trace=false;

 


call
 count
 Cpu
 elapsed
 disk
 query
 current
 rows
 
Parse
 1
 0.01
 0.00
 0
 1
 0
 0
 
Execute
 1
 0.00
 0.00
 0
 0
 0
 0
 
Fetch
 2
 0.02
 0.01
 0
 223
 0
 1
 
total
 4
 0.03
 0.01
 0
 224
 0
 1
 


 


Rows
 Row Source Operation
 
1
 SORT AGGREGATE
 
2000
 FILTER
 
13000
 HASH JOIN OUTER
 
13000
 TABLE ACCESS FULL T1
 
11000
 INDEX FAST FULL SCAN (object id 108538)
 


结论: 经过分析以后,使用了HASH JOIN,效率提高很明显.这是一个正确的查询计划.

 

总结:这四种查询模式中使用外连接的效率最高.

五. 在10G中测试
T1: 10000
T2: 9800

NOT IN


call
 count
 Cpu
 elapsed
 disk
 query
 current
 rows
 
Parse
 1
 0.00
 0.00
 0
 0
 0
 0
 
Execute
 1
 0.00
 0.00
 0
 0
 0
 0
 
Fetch
 2
 7.65
 7.47
 135
 685810
 0
 1
 
total
 4
 7.65
 7.47
 135
 685810
 0
 1
 


执行计划:


Rows
 Row Source Operation
 
1
 SORT AGGREGATE (cr=685810 pr=135 pw=0 time=7479614 us)
 
200
 FILTER  (cr=685810 pr=135 pw=0 time=7474258 us)
 
10000
 TABLE ACCESS FULL T1 (cr=138 pr=135 pw=0 time=40407 us)
 
9800
 TABLE ACCESS FULL T2 (cr=685672 pr=0 pw=0 time=7366891 us)
 


对T1进行分析后

call
 count
 Cpu
 elapsed
 disk
 query
 current
 rows
 
Parse
 1
 0.00
 0.01
 0
 3
 0
 0
 
Execute
 1
 0.00
 0.00
 0
 0
 0
 0
 
Fetch
 2
 0.01
 0.01
 22
 165
 0
 1
 
total
 4
 0.01
 0.02
 22
 168
 0
 1
 


执行计划:

Rows
 Row Source Operation
 
1
 SORT AGGREGATE (cr=165 pr=22 pw=0 time=15933 us)
 
200
 HASH JOIN ANTI (cr=165 pr=22 pw=0 time=15973 us)
 
10000
 TABLE ACCESS FULL T1 (cr=138 pr=0 pw=0 time=10075 us)
 
9800
 INDEX FAST FULL SCAN IX_T2 (cr=27 pr=22 pw=0 time=10529 us)(object id 52081)
 


另外, 通过对NOT EXISTS的分析,发现它的效率要好于MINUS,这也是一个变化.

 

六. 结束语
从上面的对比分析,可以得出这样的结论:

10G的CBO要比9i的CBO智能了不少, 对于NOT IN 和NOT EXISTS 这两种使用频率较高的语句,能使用最优的查询计划.

 

视频异常检测 5 大经典数据集实战对比:UCSD Ped2 vs CUHK Avenue vs Street Scene 本文深入对比分析了视频异常检测领域的五大经典数据集,包括UCSD Ped2、CUHK Avenue和Street Scene等,从场景复杂度、异常类型和标注质量等多维度进行实战评估。通过详细的数据集特性解析和计算效率测试,为研究者和工程师提供选型指导,帮助优化算法在智能监控和安防领域的应用效果。 阅读详情

相关推荐

【AUTOSAR】MCU Port的配置(MCAL)【EB】

熟悉Classic AUTOSAR架构的朋友应该知道,经常需要用到MCU中的Port这个模块。那么如何通过工具快速配置一个Port呢?

xinsuiwodong2014的博客 9513

oracle取差集效率如何,Oracle Minus 取差集

Oracle MinuskeywordSQL中的MINUSkeywordSQL中有一个MINUSkeyword,它运用在两个SQL语句上,它先找出第一条SQL语句所产生的结果,然后看这些结果有没有在第二个SQL语句的结果中。假设有的话,那这一笔记录就被去除,而不会在最后的结果中出现。假设第二个SQL语句所产生的结果并没有存在于第一个SQL语句所产生的结果内,那这笔资料就被抛弃,其语法例如以下:[S...

weixin_29761519的博客 495

单细胞分析实战:用R语言绘制带连线的堆叠柱状图(附完整代码)

本文详细介绍了如何使用R语言绘制带连线的堆叠柱状图进行单细胞转录组数据分析,特别适用于展示细胞比例变化趋势。通过完整代码示例和实战技巧,帮助研究者优化多组别比较的可视化效果,提升科研图表质量。

yhn4567890的博客 390

Oracle-性能优化(二)

Oracle-性能优化(二)

bk_huangzongbo的博客 584

别再只会用555了!手把手教你用运放和RC电路搭一个50Hz正弦波信号源(附Multisim仿真文件)

本文详细介绍了如何使用运放LM358和RC电路搭建一个精准的50Hz正弦波信号源,涵盖文氏电桥核心原理、单电源供电解决方案、Multisim仿真及实物调试技巧。通过实战指南和优化建议,帮助电子爱好者快速掌握低频信号生成技术,适用于各种测试和校准场景。

weixin_34116482的博客 365

三菱FX5U运动控制(步进)

三菱FX5U脉冲定位控制,原点回归,相对定位,绝对定位,运动控制案例。

weixin_55762091的博客 1万+

oracle minus 利用率,oracle 两表数据对比---minus

1 引言在程序设计的过程中,往往会遇到两个记录集的比较。如华东电网PMS接口中实现传递一天中变更(新增、修改、删除)的数据。实现的方式有多种,如编程存储过程返回游标,在存储过程中对两批数据进行比较等等。本文主要讨论利用ORACLE的MINUS函数,直接实现两个记录集的比较。2 实现步骤假设两个记录集分别以表的方式存在,原始表为A,产生的比较表为B。2.1 判断原始表和比较表的增量差异利用MINUS...

weixin_31089065的博客 430

Xilinx FPGA平台DDR3设计保姆式教程(3)MIG IP核使用教程及DDR读写时序

干货来了,用DDR搬砖,只需要会用IP就好,Xilinx官方YYDS! ----------------------------------------------------------------------------------------------------------------- 汇总篇: Xilinx平台DDR3设计保姆式教程(汇总篇)——看这一篇就够了 ----------------------------------------------------------...

数字IC/FPGA杂货铺,找一找,或许有你想要的~ 2万+

一个老话题: MINUS,外连接,NOT IN,NOT EXISTS 的效率比较

<br />关于 MINUS,外连接,NOT IN,NOT EXISTS 的效率比较,绝对是一个很老很老的话题了.<br />如果要完成这个需求:"取出一些记录,在表A中,不在表B中", 你会采用哪种方案?为什么会采用这种方案?<br />我作了一个实验, 发现随着数据库版本的不同,CBO的工作方式也有变化.<br />本文仅限于一般性的分析, 不涉及internal.<br /> <br />一.  概述<br />首先, 我必须纠正自己的一个"错误认识": MINUS的效率很低.<br />针对上面提到

旺仔专栏 4427

uniapp | 基于高德地图实现位置选择功能(安卓端)

在uni-app项目中实现地图位置选择功能的解决方案。由于uni.chooseLocation功能受限,采用高德地图API自主开发。系统由父组件poiMap.vue(负责展示和跳转)和子组件poiBox.vue(核心地图逻辑)构成,通过父子组件通信传递位置数据。关键技术包括:1)使用AMapLoader动态加载地图SDK;2)集成PositionPicker实现拖拽选点;3)异步加载AMapUI插件;4)通过事件监听获取位置详情(地址/经纬度)。

大胆尝试,小心实践 733

innovus:像ICC2一样设置placement label

ICC2有placement label/placement rule功能,能控制各种类型cell 之间的spacing规则,包括top和bottom edge的spacing。innovus也有相同的功能,以下示例方便大家了解用法。我们需要给所有OAI* cell之间设置一个spacing rule,让他们不要上下或者挨着。效果如下图,这个spacing指的是同一边的间距,不是cell间距。我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧?

m0_61544122的博客 833

NOT EXIST和NOT IN 和MINUS的用法

①NOT EXISTS一般都会比较慢 UPDATE  A SET DATE=sysdate WHERE LINK_TAISHOGAI_FG = '0'     AND NOT EXISTS (SELECT 1  FROM   FROM   B  WHERE  A.ID1= B.ID1  AND    A.ID2 = B.ID2  AND   A.ID3 = B.ID3  A

1460

Docker(八):Docker Compose(容器编排) 管理多容器应用—实战案例演示

🟢 Docker(八):Docker Compose(容器编排) 管理多容器应用—实战案例演示

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 6万+

sql中not in 、minus 、not exists效率问题

例子: create table A ( num number(10)); create table B ( num number(10)); 表A中记录为1 2 3 9 表B中记录为2 3 4 5 现在要查询出1 9,可以用下面三个语句 (1)select a.num from A a where a.num not in (select b.num from B b);...

iteye_4609的博客 1310

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

oracle中minus什么意思,Oracle Minus关键字

Oracle Minus关键字SQL中的MINUS关键字SQL中有一个MINUS关键字,它运用在两个SQL语句上,它先找出第一条SQL语句所产生的结果,然后看这些结果有没有在第二个SQL语句的结果 中。如果有的话,那这一笔记录就被去除,而不会在最后的结果中出现。如果第二个SQL语句所产生的结果并没有存在于第一个SQL语句所产生的结果内,那这 笔资料就被抛弃,其语法如下:[SQL Segment 1...

weixin_39957934的博客 1146

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

oracle 获取两张表的差集_Oracle Minus 取差集

Oracle MinuskeywordSQL中的MINUSkeywordSQL中有一个MINUSkeyword,它运用在两个SQL语句上,它先找出第一条SQL语句所产生的结果,然后看这些结果有没有在第二个SQL语句的结果中。假设有的话,那这一笔记录就被去除,而不会在最后的结果中出现。假设第二个SQL语句所产生的结果并没有存在于第一个SQL语句所产生的结果内,那这笔资料就被抛弃,其语法例如以下:[S...

weixin_27744023的博客 3099

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

oracle minus 是什么意思,oracle minus用法

Oracle Minus关键字SQL中的MINUS关键字SQL中有一个MINUS关键字,它运用在两个SQL语句上,它先找出第一条SQL语句所产生的结果,然后看这些结果有没有在第二个SQL语句的结果 中。如果有的话,那这一笔记录就被去除,而不会在最后的结果中出现。如果第二个SQL语句所产生的结果并没有存在于第一个SQL语句所产生的结果内,那这 笔资料就被抛弃,其语法如下:[SQL Segment 1...

weixin_35014204的博客 1180

通过sql trace比较常规 not in 、minus、not exists效率

测试目的:业务中,有两张表,A 表数据900w,B表数据3200w。A表的表结构字段包含B表表结构所有字段,现在要求出A表中不存在B表中的数据。针对现网,模拟做了如下实验。1:在无索引的状态下,比较 not in、minus及n...

congji3615的博客 425

oracle minus 利用率,Oracle Minus 取差集(也可以用来做分页,但效率不高)

Oracle Minus关键字SQL中的MINUS关键字SQL中有一个MINUS关键字,它运用在两个SQL语句上,它先找出第一条SQL语句所产生的结果,然后看这些结果有没有在第二个SQL语句的结果中。如果有的话,那这一笔记录就被去除,而不会在最后的结果中出现。如果第二个SQL语句所产生的结果并没有存在于第一个SQL语句所产生的结果内,那这笔资料就被抛弃,其语法如下:[SQL Segment 1]M...

weixin_30847063的博客 378

minus/not in/not exists的原理和效率

http://www.itpub.net/viewthread.php?tid=984425&amp;extra=&amp;page=3 minus: [ CODE: Select *From gal_voucher_item itemWhere item_iid In (Select item_iid                                  From ...

心似海 281

[Oracle] minus 和 not exists比较

SQL> select count(*) from test; COUNT(*) ---------- 28835328 Elapsed: 00:00:09.48 SQL> select c...

cizhiyou2391的博客 715

oracle中in的效率,oracle中exists与in效率及其用法

2) select * from t1 where t1.a in (select t2.a from t2) ;t1数据量非常大而t2数据量小时,t1>>t2 时,2) 的查询效率高。union把两张表的数据合起来,如有重复行,只取一行union all把两张表的数据合起来,不过滤重复行minus返回在第一个查询结果中与第二个查询结果不相同的那部分行记录。oracle有这样的一些约定...

weixin_28698129的博客 1778

mysql oracle minus_Oracle Minus关键字

OracleMinus关键字 //创建表1 create table test1 ( name varchar(10), sex varchar(10), age int ); insert into test1values('luxin','female',25); insert into test1 values('tom','female',26); insert into test1 va...

weixin_34282589的博客 293
上一篇: velocity配置
下一篇: event.srcElement
msg_java2011
博客等级 码龄15年 18粉丝 45原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值