oracle开发系列(三)exists&not exists用法(10g)

注:以下内容适合 初学oracle开发或者java等开发者,高手略过

一 exists&in

以下三个语句  功能都是从 iodso.qos_hisentry_sheet_jtext_td 里面找到  sheet_no在  iodso.qos_hisentry_sheet_td表 arch_time 1天时间里面的单子。

iodso.qos_hisentry_sheet_jtext_td 有个普通的联合索引                  

iodso.qos_hisentry_sheet_td  有个普通的索引                                  

两个表的数据量情况

select count(1) from iodso.qos_hisentry_sheet_td-- 29843027

select count(1) from  iodso.qos_hisentry_sheet_jtext_td--29973242

1

select *
  from iodso.qos_hisentry_sheet_jtext_td t
 where t.sheet_no in (select a.sheet_no
                        from iodso.qos_hisentry_sheet_td a
                       where a.arch_time between trunc(sysdate - 1, 'dd') and
                             trunc(sysdate, 'dd'));

2

select *
  from iodso.qos_hisentry_sheet_jtext_td t
 where t.sheet_no in (select a.sheet_no
                        from iodso.qos_hisentry_sheet_td a
                       where a.arch_time between trunc(sysdate - 1, 'dd') and
                             trunc(sysdate, 'dd')
                         and t.sheet_no = a.sheet_no);

3

select *
  from iodso.qos_hisentry_sheet_jtext_td t
 where exists (select a.sheet_no
          from iodso.qos_hisentry_sheet_td a
         where a.arch_time between trunc(sysdate - 1, 'dd') and
               trunc(sysdate, 'dd')
           and t.sheet_no = a.sheet_no);

执行计划比较

执行计划由pl/sql Dev的F5键生成  ,一般看执行计划会建议从sqlplus explain plan for看 但是开发者可能更习惯用pl、sql工具

且工具能定位到第一个执行的地方  且对应的操作描述 在最下方有一串英文 如下图 sort_unique 的解释 在最下面红圈的地方 sort a result set and eliminate duplicates 意思是对结果集排序并且去重

sql 1 的计划:

sql 3 的计划:

sql 2的计划:

从上面的执行计划及顺序来看 三个sql 完全一样。

执行结果

sql 1的执行结果:

sql2 的执行结果:

sql3 的执行结果:

从以上来看 是sql1 执行的最快 sql2 执行的最慢

上面是从查小表的情况 再看看下面语句的情况(查大表的情况):

1

select a.*
  from iodso.qos_hisentry_sheet_td a
 where a.arch_time between trunc(sysdate - 1, 'dd') and
       trunc(sysdate, 'dd')
   and sheet_no in
       (select sheet_no from iodso.qos_hisentry_sheet_jtext_td t);

2

select a.*
          from (select *
            from iodso.qos_hisentry_sheet_td a
           where a.arch_time between trunc(sysdate - 1, 'dd') and
                 trunc(sysdate, 'dd')) a
         where exists (select t.sheet_no
                  from iodso.qos_hisentry_sheet_jtext_td t
                 where t.sheet_no = a.sheet_no);

所以 网上很多说的 exists 比 in快 或者 检索大表的时候 exists比 in快 等等 不一定都是准确的,现在百度的很多东西可能都是复制来复制去,还有的是以前8i 9i老版本的规则 现在基本都是10g以上 不一定适用。网上的结论要慎用 最好自己试验下。

exists 和 in的效率通常情况是差不多的,需要看执行计划及实际上执行时间为准,。

ps:大部分的企业级开发者可能更喜欢用in 易于平常的思维理解

二 not exists&not in

1

select t.occur_area_id-1,
  COUNT(1) ALL_NUM,
   SUM(CASE
             WHEN (DECODE(SIGN(T.FLOW_TIME - t.fact_flow_time), -1, 0, 1) = 0) THEN
              1
             ELSE
              0
           END) CS_NUM
  from  QOS_NET_CONTROL_GD_sb T
where t.sheet_no not in
(SELECT  t1.sheet_no
  FROM QOS_NET_CONTROL_GD_sb T1,
IODSO.QOS_EOSORG_T_EMPLOYEE     T2,
          IODSO.QOS_EOSORG_T_ORGANIZATION T3,
       iodso.qos_eosoperator t6
 WHERE T1.USERID = T6.userid
   and t6.operatorid = t2.operatorid
   and t2.orgid=t3.orgid
 and T1.STAT_DATE = TO_DATE('2014-11-08', 'YYYY-MM-DD')
   AND T1.STAT_DATE = TO_DATE('2014-11-08', 'YYYY-MM-DD')
)
group by t.occur_area_id;

2

select t.occur_area_id - 1,  
       COUNT(1) ALL_NUM,  
       SUM(CASE  
             WHEN (DECODE(SIGN(T.FLOW_TIME - t.fact_flow_time), -1, 0, 1) = 0) THEN  
              1  
             ELSE  
              0  
           END) CS_NUM  
  from QOS_NET_CONTROL_GD_sb T  
 where not exists  
 (select 1  
          from QOS_NET_CONTROL_GD_sb           s,  
               IODSO.QOS_EOSORG_T_EMPLOYEE     T2,  
               IODSO.QOS_EOSORG_T_ORGANIZATION T3,  
               iodso.qos_eosoperator           t6  
         where T.Sheet_No = s.sheet_no  
           and s.USERID = T6.userid  
           and t6.operatorid = t2.operatorid  
           and t2.orgid = t3.orgid)  
           and T.STAT_DATE = TO_DATE('2014-11-08', 'YYYY-MM-DD')  
 group by t.occur_area_id

从上面执行计划可以看到 cost 差别很大 ,not exists 比not in 的小很多。 not exists使用的是hash join anti 而 not in 使用的是filter。执行时间来看 not exists 几分钟 not in 执行了30分钟还没完成。

小总结:(此内容转)

Semi-join

通常出现在使用了exists或in的sql中,所谓semi-join即在两表关联时,当第二个表中存在一个或多个匹配记录时,返回第一个表的记录;

与普通join的区别在于semi-join时,第一个表里的记录最多只返回一次

Anti-join

第二张表没有发现匹配记录时,才会返回第一张表里的记录;

何时选择anti-join1

使用not in且相应列有not null约束

not exists,不保证每次都用到anti-join

当无法选择anti-join时,oracle常会采用filter替代

filter

是对外表的每一行,都要对内表执行一次全表扫描,他其实很像我们熟悉的neested loop,但它的独特之处在于会维护一个hash table

三 两个表根据某字段关联更新

update ap
   set ap.t =
       (select bp.t from bp where ap.s = bp.s)
 where exists (select 1 from bp where ap.s = bp.s);
commit;

语句看似很简单 但是当ap  bp本身都是很复杂的查询的时候 可能想到这个比较困难了。

时间: 2024-08-18 17:39:04

oracle开发系列(三)exists&not exists用法(10g)的相关文章

oracle开发系列(五) 取左表不在右表记录的3种方法-引申到db2

引: 我们在做数据库开发用 pl sql 加工数据时,经常会遇到取a表不在b表中的记录 或者 左表不在右表中的记录 的情况,所以特地对此做个简单的总结,以便以后用到回顾. 解决: 取a表某字段不在b表 我们自然的逻辑会想到用 a not in b ,这是第一种方法 1 not in 如下图 ,数据库为不跑业务的测试数据库,两张表的数据量一样, 用not in 可以找出a表中prd_inst_id不在t表中的记录 如下图,为生产库的表  l 和t表数据量相同,数据量900w左右 2 not exs

短信开发系列(三):短信接收引擎

短信开发系列目录: 短信开发系列(一):GSM手机短信开发初探短信开发系列(二):GSM手机短信开发之短信解码短信开发系列(三):短信接收引擎 之前写了短信接收处理的一些内容,今年事情实在太多了,就停顿了这么一大段的时间.接下来会继续完成相关的内容. 今天先写用之前写的短信类库的一个应用,短信接收引擎.可以用在处理一些短信的提醒:作为前面两篇文章的一个实战运用,可以作为一个多线程.委托和事件.串口等方面知识的一个综合运用. 先来分析一下整个程序的流程: - 启动线程 - 定时运行线程主函数 -

S5PV210开发系列三_简易Bootloader的实现

S5PV210开发系列三 简易Bootloader的实现 象棋小子          1048272975 Bootloader是嵌入式系统上电后第一段执行的代码.对于功能简单的处理器,可能并没有Bootloader的概念,但对于应用处理器,有不同的启动方式,不同的存储设备(Nand flash.sd/mmc.DDR2.SRAM等),不同的操作系统等,往往需要一个Bootloader先初始化CPU和相关的硬件,建立内存空间映射,把内核或应用程序加载到相应的内存执行位置,最后调用内核或应用程序,释

【Qt编程】基于Qt的词典开发系列<三>--开始菜单的设计

这篇文章讲讲如何实现开始菜单(或者称为主菜单)的设计.什么是开始菜单呢?我们拿常用的软件来用图例说明,大多数软件的开始菜单在左下角,如下图: 1.window 7的开始菜单 2.有道词典的主菜单 3.QQ的开始菜单 4.我写的词典软件的开始菜单 当你左键单击开始菜单时,就会弹出相应的菜单选项,然后你就可以进行相关操作.本文只讲如何实现点击按钮,弹出菜单功能,至于点击菜单后的事件需要你自己编写.当然,关于右击按钮出现菜单的方法,则是要重写qt自带的函数,至于具体操作可以百度. 要想使按钮实现左键单

【Qt编程】基于Qt的词典开发系列<三>--界面美化设计

本文讲一讲界面设计,作品要面向用户,界面设计的好坏直接影响到用户的体验.现在的窗口设计基本都是扁平化的,你可以从window  XP与window 8的窗口可以明显感觉出来.当然除了窗口本身的效果,窗口中各种控件的特效也是特别重要的一环.下面讲讲我在词典软件中的一些设计:说到界面美化的设计,不得不提到美工,一个好的美工是想当的重要!软件毕竟少不了图标,而不懂美工的我,也就只能在网上使用别人的图标了. 如何得到网上的图标? 直接百度就可以了,当然还有另一种方法:就是从别人的文件中提取这些图标文件.

BizTalk开发系列(三十三)BizTalk之Excel终极解决方案

Excel作为优秀的客户端数据处理程序得到了广泛的应用. 由于其简单又强大的功能在很多公司或个人的数据处理中占用非常重要的位置. 而BizTalk作为微软的SOA主打产品虽然免费提供了很多Adapter支持各种协议及应用程序. 不过非常可惜没有提供对富客户端程序Excel的"原生态"支持. 所以我们只能自己查找解决办法. 应用程序对Excel的支持网上已经有很多解决方案的,一部分是使用ODBC的excel驱动将Excel作为数据源进行处理,对于规范数据表之类的Excel文档这种方法比较

oracle开发系列(三)TABLE ACCESS BY INDEX ROWID 你不知道的索引回表

1 引言 最近系统经常提示一个sql查询时间过长的问题,看了一下就是一个每天按照时间戳统计前一天量的sql. 表总的数据量为53483065. 语句如下: select count(x.serial_id) as countnum from iodso.qos_cnst_busilog_td x where x.oper_time between trunc(sysdate- 1) and trunc(sysdate); 执行时间情况如下:(执行要49s) 看了下执行计划 是这样的: 从上面的执

oracle开发系列(一)让人抓狂的错误之 null值 与 无值(无结果)

最近,在做开发.写存过的时候碰到一些问题,找了好长时间才发现原因,而且是以前不知道的.所以在这给记下来 给自己备忘和大家参考. 一 .null值 下面举个最简单的例子,平常工作当中肯定比这个sql复杂的多,在这只是把这个易错点呈现出来,他可能是一个复杂sql出错的小的 不容易被发现的一个问题. 上面是一个很简单表的所有数据.area_num 区域编码 area_name 区域名称 delflag 有无效标识 1有效 0无效(其中淮北 和宣城的delflag为null). 现在想找出有效的那些区域

BizTalk开发系列(三十八)微软BizTalk Server定价和许可[解读]

做BizTalk的项目一段时间了,但是对BizTalk的价格和许可还不是很了解.给客户设计解决方案时大部分产品都是直接按照企业版的功能来设计,很 少考虑到价格和许可方面的因素,以为这个不是我们的事情或者认为使用企业版是应该的,企业软件的销售就是有意思,懂产品的和卖产品的一般不是一个人.懂产 品的一般是做技术的,学这个产品的时候就是用D版的或者是企业版,不会去关心不同产品的定价.当然在跟客户讲的时候就很少考虑版本及价格因素.而卖产品就 会添油加醋说要实现这样的平台您需要购买XX.YY产品,当然为要