通过ORACLE分析函数过滤重复数据

简介:
  今天,确切的讲应该是昨天下午,研发的同事突然向我寻求SQL技术支援。
      看看他的问题,比较麻烦些。
    
select sbl.fee_terminal_id , sbl.status, smr.status, smr.report_time
     from XXX_log sbl, XXX_report smr
where sbl.task_id  in ('8888','9999','1111','2222')
      and sbl.msg_id=smr.msg_id(+)
      and sbl.submit_time>= '20080927'
      and sbl.submit_time<= '20080929'
      and smr.report_time>= '20080927'
      and smr.report_time<= '20080929'
      and (fee_terminal_id, report_time)  in (
              select  distinct(sbl.fee_terminal_id),  max(smr.report_time)
                  from XXX_log sbl, XXX_report smr
                 where sbl.task_id  in ( '8888', '9999', '1111', '2222')
                     and sbl.msg_id=smr.msg_id(+)
                     and sbl.submit_time>= '20080927'
                     and sbl.submit_time<= '20080929'
                     and smr.report_time>= '20080927'
                     and smr.report_time<= '20080929'
                 group  by fee_terminal_id
     );
      
      他需要提取某个时间段内,某个ID(fee_terminal_id)最新时间的状态。其实如果是在一张表中,直接MAX(report_time)就可以了。但是,恰恰这是两张表。每张表中一个状态,通常的情况就是我们首先得到ID及其最大的(最新)报告时间,然后再“自连接”自己进行WHERE条件的查询。
      上面的SQL就是通过这种基本的想法来实现的。
      一般情况下,应该是没有问题的。但是,这次问题却出现了。主要就是数据太大,执行了30分钟没有看到有结果集返回。
       首先因为两张基本表(XXX_log sbl, XXX_report smr)都是分区表,不然数据也不会这么大呀。进行必要的分区工作,要知道,再精良的SQL,数据太多也会有问题。优化的第一步就是“少做”(片面一点讲,性能真的是设计出来的)。
       完成后,直接执行原始SQL,基本上180秒左右,可以看到结果集返回。
       至此,都有些“跑题”,还有过滤重复呢(其实就是找出最新时间的ID状态即可)。
       看着这句SQL我总是有些不死心,看看其实这句SQL的两个部分的SQL语句基本相同,其实一部分就可以得到所有信息,就是因为数据无法得到ID和最新时间对应的值在一句话中。
       突然想起了ORACLE的分析函数。OK,使用
       LAG
      
select a,b,c,d
         from ( select sbl.fee_terminal_id a,
                                                         sbl.status b,
                                                         smr.status c,
                                                         smr.report_time d,
                                                         lag(sbl.fee_terminal_id,1,0)  over(partition  by sbl.fee_terminal_id  order  by smr.report_time  desc) flag
                                         from xxx_log sbl, xxx_report smr
                                  where sbl.task_id  in ( '8888', '9999', '1111', '2222')
                                          and sbl.msg_id = smr.msg_id(+)
                                          and sbl.submit_time >=  '20080927'
                                          and sbl.submit_time <=  '20080929'
                                          and smr.report_time >=  '20080927'
                                          and smr.report_time <=  '20080929')
where flag = 0

      优化了原SQL语句。
      执行成本从19106下降到10139,结果集返回的时间下降到15秒左右。响应时间有大幅提高。
      总结:
      此次优化的核心思想,减少SQL的重复执行,能在一句SQL中执行完成的,就不要放到两句或者是多个子查询中执行。
       通过使用分析函数LAG,将分类和排序一次完成。一定要多多尝试使用分析函数,往往会给你带来非常的惊喜。
       

       BTW,国庆节快乐。-:)

本文转自Be the miracle!博客51CTO博客,原文链接http://blog.51cto.com/miracle/102792如需转载请自行联系原作者


Larry.Yue

相关文章
|
存储 Oracle 关系型数据库
【YashanDB 知识库】YMP 校验从 yashandb 同步到 oracle 的数据时,字段 timestamp(0) 出现不一致
在YMP校验过程中,从yashandb同步至Oracle的数据出现timestamp(0)字段不一致问题。原因是yashandb的timestamp(x)存储为固定6位小数,而Oracle的timestamp(0)无小数位,同步时会截断yashandb的6位小数,导致数据差异。受影响版本:yashandb 23.2.7.101、YMP 23.3.1.3、YDS联调版本。此问题会导致YMP校验数据内容不一致。
|
Oracle 关系型数据库 Linux
【YashanDB 知识库】通过 dblink 查询 Oracle 数据时报 YAS-07301 异常
客户在使用 YashanDB 通过 yasql 查询 Oracle 数据时,遇到 `YAS-07301 external module timeout` 异常,导致 dblink 功能无法正常使用,影响所有 YashanDB 版本。原因是操作系统资源紧张,无法 fork 新子进程。解决方法包括释放内存、停掉不必要的进程或增大进程数上限。分析发现异常源于 system() 函数调用失败,返回 -1,通常是因为 fork() 失败。未来 YashanDB 将优化日志信息以更好地诊断类似问题。
|
Oracle 关系型数据库 Java
【YashanDB知识库】Flink CDC实时同步Oracle数据到崖山
本文介绍通过Flink CDC实现Oracle数据实时同步至崖山数据库(YashanDB)的方法,支持全量与增量同步,并涵盖新增、修改和删除的DML操作。内容包括环境准备(如JDK、Flink版本等)、Oracle日志归档启用、用户权限配置、增量日志记录设置、元数据迁移、Flink安装与配置、生成Flink SQL文件、Streampark部署,以及创建和启动实时同步任务的具体步骤。适合需要跨数据库实时同步方案的技术人员参考。
【YashanDB知识库】Flink CDC实时同步Oracle数据到崖山
|
SQL 运维 Oracle
【迁移秘籍揭晓】ADB如何助你一臂之力,轻松玩转Oracle至ADB的数据大转移?
【8月更文挑战第27天】ADB(Autonomous Database)是由甲骨文公司推出的自动化的数据库服务,它极大简化了数据库的运维工作。在从传统Oracle数据库升级至ADB的过程中,数据迁移至关重要。
348 0
|
存储 Oracle 关系型数据库
【YashanDB 知识库】YMP 校验从 yashandb 同步到 oracle 的数据时,字段 timestamp(0) 出现不一致
【YashanDB 知识库】YMP 校验从 yashandb 同步到 oracle 的数据时,字段 timestamp(0) 出现不一致
|
数据采集 Oracle 关系型数据库
实时计算 Flink版产品使用问题之怎么实现从Oracle数据库读取多个表并将数据写入到Iceberg表
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
Oracle 关系型数据库 Linux
【YashanDB知识库】通过dblink查询Oracle数据时报YAS-07301异常
【YashanDB知识库】通过dblink查询Oracle数据时报YAS-07301异常
|
SQL 存储 Oracle
【YashanDB知识库】Oracle pipelined函数在YashanDB中的改写
【YashanDB知识库】Oracle pipelined函数在YashanDB中的改写
|
Oracle 关系型数据库 Linux
【YashanDB 知识库】通过 dblink 查询 Oracle 数据时报 YAS-07301 异常
某客户在使用 YashanDB 通过 yasql 查询 Oracle 数据时,遇到 `YAS-07301 external module timeout` 异常,导致 dblink 功能无法正常使用,影响所有版本。问题源于操作系统资源紧张,无法 fork 新子进程。解决方法包括释放内存、停掉不必要的进程或增大进程数上限。分析发现异常原因为系统调用 fork() 失败。经验总结:优化日志记录,提供更多异常信息。
|
存储 Oracle 关系型数据库
【YashanDB知识库】YMP校验从yashandb同步到oracle的数据时,字段timestamp(0)出现不一致
【YashanDB知识库】YMP校验从yashandb同步到oracle的数据时,字段timestamp(0)出现不一致

推荐镜像

更多