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

1553B通信项目开发笔记(一)协议概述 最近接了个项目,需要用1553B协议通信,仅作为RT端口进行通信,控制器采用ARM 使用芯片为国产的BU61580芯片,功能和引脚和DDC的61580完全一致。 阅读详情

关于 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 这两种使用频率较高的语句,能使用最优的查询计划.

 

博文来源:http://lovewinter.itpub.net/post/493/5599

 

 

【Burp入门第二篇】Chrome配置BurpSuite代理教程 1、配置Burp代理为127.0.0.1:80802、扩展商店添加插件switchyomega,修改服务器和端口为下图:3、打开代理,选择刚才添加的代理 阅读详情

相关推荐

LeGo-LOAM源码篇:源码分析(3)

mapOptmization.cpp,主要内容包括回环检测、scan-to-map位姿优化、因子图。

slamml 1382

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

Gromacs实战:从蛋白质-小分子对接到分子动力学模拟全流程解析

本文详细解析了使用Gromacs进行蛋白质-小分子对接和分子动力学模拟的全流程,包括文件准备、拓扑生成、复合物构建、溶剂化处理、能量最小化及平衡模拟等关键步骤。通过实战案例,帮助研究者验证药物分子与靶标蛋白的结合稳定性,提升分子动力学模拟的效率和准确性。

weixin_29216353的博客 385

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

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

msg_java2011的专栏 4582

Android音频混音器AudioMixer实战:从多路输入到设备播放的完整流程解析

本文深入解析了Android平台上音频混音器AudioMixer的完整工作流程,涵盖从多路音频输入、轨道创建与配置、AudioBufferProvider数据源接入,到核心混音处理与最终设备播放的全过程。文章重点探讨了如何高效管理音频数据流、配置音量与重采样参数,并提供了缓冲区管理与性能优化的实战技巧,帮助开发者构建稳定、低延迟的音频应用。

l3m4n的博客 342

《IC验证必看|IC验证的全流程概览(从DUT到回归交付)》

本文系统介绍了IC验证的全流程,从理解设计需求到最终交付验证结果。主要内容包括:1)深入理解DUT的功能和接口;2)制定详细的测试计划(Testplan);3)搭建UVM验证平台;4)执行定向和随机测试并进行回归;5)分析功能、代码和断言覆盖率;6)交付完整的验证报告。文章强调验证是一个闭环过程,特别指出新手容易忽视测试计划和覆盖率分析这两个关键环节,导致验证不充分。文末还提出思考题,引导读者反思验证计划的制定方法。

m0_46663240的博客 1261

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

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

congji3615的博客 425

基于深度学习的番茄成熟度检测系统——YOLOv5、YOLOv8、YOLOv10及UI界面的实现

YOLO是一种快速且准确的目标检测模型,近年来,YOLOv5、YOLOv8和YOLOv10作为YOLO系列的重要版本,分别在速度、精度和效率上进行了优化。下面我们简要介绍这些模型。本文介绍了如何基于YOLOv5、YOLOv8和YOLOv10等深度学习模型,结合PyQt5设计一个番茄成熟度检测系统。通过训练模型、优化算法和设计用户友好的界面,我们能够构建一个高效且准确的番茄成熟度检测系统,广泛应用于农业自动化和智能化管理中。

YOLO 1002

Oracle之minus求差集(与该功能相同的有not in、not exists)

minus语法:A minus B只去除A跟B的交集部分,将A剩余自己独有的部分输出显示。(1)minus语法(2)minus解释 与minus功能相同的有(not in、not exist)关键字 例子(1)原表(2)例子1:部分相同(3)例子2:完全相同 ...

侯风飞的博客 1889

157、飞控中的鲁棒自适应控制

本文总结了飞控系统中鲁棒自适应控制的实践经验。作者通过炸机案例引出传统PID控制的局限性,分析了鲁棒性与自适应性的本质矛盾,提出"用鲁棒性兜底,用自适应性提性能"的设计原则。重点介绍了模型参考自适应控制(MRAC)的实现方法,包括参考模型设计、自适应律调参技巧(建议初始增益设为0.01)、直接/间接自适应的应用场景差异,以及防止参数漂移的鲁棒修正方法。文章还分享了实际调试中的三大关键问题(初始值设定、激励条件、执行器饱和)及解决方案,并推荐了"鲁棒PID+自适应前馈"的混合架构。最后强调调试顺序应为先保证鲁

2401_88858637的博客 27

uniapp(全端兼容) - 实现点击输入框时完美顶起键盘,获取键盘高度动态计算顶起距离,解决软键盘弹出时输入框被覆盖问题,uniapp微信小程序/移动端h5网页/安卓苹果app(示例代码,一键复制

uniapp,支付宝微信小程序,移动端H5网页网站,软键盘弹出位置不对,软键盘挡住了输入框怎么办,获取键盘高度计算弹出距离,uniapp如何解决输入框input激活后键盘弹出遮挡问题,uniapp输入框偶尔被键盘遮挡,解决uniapp在App环境下输入框被软键盘遮挡的问题,uniapp 完美解决苹果和安卓input框遮挡兼容问题,uniapp输入框拉起软键盘时,输入框显示不全,被软键盘挡住一半,input被键盘遮挡的解决方案,软键盘遮挡输入框,uniapp软键盘顶不起来输入框,输入框没有被软键盘弹出来怎么办

✅ 精选推荐文章 1万+

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

深入探讨 SAP ERP 物料主数据中的 Valuation Type

在 SAP ERP 系统中,是用于区分同一种物料在不同条件下的估价方法。物料的估价可以因产地、质量等级、供应商或批次的不同而有所差异。通过为物料设置不同的估价类别,使企业能够对这些差异进行有效管理。为了实现更细致的物料成本核算,SAP 系统通过(分批估价)功能允许为同一物料设置多个估价类型。这种方法特别适合那些在来源、质量、或其他参数上存在显著差异的物料。是 SAP ERP 和 SAP S/4HANA 中物料主数据的核心组成部分,为企业提供了灵活的成本管理工具。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1408

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

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

weixin_29761519的博客 495

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

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

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

weixin_39957934的博客 1146

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

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

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

weixin_27744023的博客 3099

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

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

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

weixin_35014204的博客 1180

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

in,not in,exists,not exists的区别

<br />转:<br /> <br />http://www.xmchinalife.com/wade/Article_Print.asp?ArticleID=283<br /> <br /> <br />exists 和 in <br />in适合内外表都很大的情况,exists适合外表结果集很小的情况。<br />http://blog.itpub.net/category/385/14461<br />exists 和 in 使用一例 <br />==========================

thy822的专栏 592
上一篇: SQL Server数据库性能优化之索引篇
下一篇: 解决Jasperreport的web 套打
hemingwang0902
博客等级 码龄20年 379粉丝 101原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值