`

子查询中使用了递归CONNECT BY巨慢的解决方案

 
阅读更多

有一段sql执行速度很慢 要50s

经查询是由于在sql的子查询中使用了递归查询导致

sql如下

select 
                  (SELECT to_char(temp.rwwcsx, 'yyyy-mm-dd')
                from (SELECT * FROM fxyd_rwdy_mx mx order by mx.rwdy_sj desc) temp
               WHERE temp.fxxx_bh in (F_GET_SJ_FXXX_BH(t.fxxx_bh))
                       --(SELECT a.fxxx_bh
                       --   FROM fxyd_rwmx a
                       --  start with a.fxxx_bh = t.fxxx_bh
                       -- CONNECT BY a.fxxx_bh = PRIOR a.sj_fxxx_bh)
                 and temp.hxcl_dm = 'RWTC'
                 and temp.rwtczt_dm = 'YXF'
                 and temp.jsjg_dm = '23407000000'
                 and rownum = 1) sj_xf_rwwcsx, --取本机关的上级下发的完成时限
             (SELECT jg.swjgcclx_bj
                FROM wd_swjg jg
               WHERE jg.swjg_dm =
                   (SELECT pc.dyry_swjg_dm
                      from (SELECT * FROM fxyd_rwdy_mx mx order by mx.rwdy_sj desc) temp,
                           fxyd_rwpc pc
                     WHERE temp.fxxx_bh in (F_GET_SJ_FXXX_BH(t.fxxx_bh))
                       --(SELECT a.fxxx_bh
                       --   FROM fxyd_rwmx a
                       --  start with a.fxxx_bh = t.fxxx_bh
                       -- CONNECT BY a.fxxx_bh = PRIOR a.sj_fxxx_bh)--原因同上
                       and temp.rwpc_bh = pc.rwpc_bh
                       and temp.hxcl_dm = 'RWTC'
                       and temp.rwtczt_dm = 'YXF'
                       and temp.jsjg_dm = '23407000000'
                       and rownum = 1)) sj_xf_jgcc --取上级下发机关的层次类型
          from FXYD_RWMX t, fxyd_ydgx_hxcl_pz hxcl, FXYD_YDGX_PZ gx
         where gx.xxly_dm(+) = t.xxly_dm
           and gx.zg_swjg_dm(+) = t.nsr_swjg_dm
           and gx.FXDJ_DM(+) = t.DJ_ZZ
           and hxcl.ydfs_dm(+) = gx.ydfs_dm
           and hxcl.dy_swjg_dm(+) = '23407000000'
           and t.jsgzzt_dm='02' 
                   and t.rwlx_dm = 'RW' 
                   and t.jsjg_dm = '23407000000' 
                   and (t.gbbz_dm is null or t.gbbz_dm = 'N') --不是被归并的信息
                   and t.rwtczt_dm = 'WDY' --WDY 包括上级下发,本级产生,下级退回,本级收回,重新应对
                   and not exists (SELECT 1 FROM fxyd_nsrbmd_lb lb WHERE lb.nsrdzdah = t.nsrdzdah)--纳税人在白名单中的过滤掉
                   and t.xxly_dm = '01'          
                   
                   order by t.nsrdzdah,t.tsjg_dm --按照推送机关排序时因为归并时,等级和应对方式

 由于一定要使用子查询递归 因此想了一个方法 将子查询的递归放到一个自己写function中 结果查询只用了10秒

create or replace function F_GET_SJ_FXXX_BH(FXXX_BH varchar2) return varchar2 is
  TYPE ref_type IS REF CURSOR;
  V_FXXX_BHS varchar2(2000);
  V_SQL varchar2(2000);
  V_INDEX number;
  V_TEMP_FXXX_BHS varchar2(2000);
  cur ref_type;
begin
  V_SQL:='SELECT a.fxxx_bh FROM fxyd_rwmx a start with a.fxxx_bh = '''||FXXX_BH||''' CONNECT BY a.fxxx_bh = PRIOR a.sj_fxxx_bh';
  --dbms_output.put_line(V_SQL);
  open cur for V_SQL;
  V_INDEX:=0;
  FETCH cur into V_TEMP_FXXX_BHS;
  while cur%FOUND LOOP
  IF V_INDEX > 0 THEN
      V_FXXX_BHS:=V_FXXX_BHS||','||V_TEMP_FXXX_BHS;
    ELSE
      V_FXXX_BHS:=''||V_TEMP_FXXX_BHS;
  END IF;
  V_INDEX:=V_INDEX+1;
  FETCH cur into V_TEMP_FXXX_BHS;
  END LOOP;
  CLOSE cur;
  V_FXXX_BHS:=V_FXXX_BHS||'';
  --dbms_output.put_line(V_FXXX_BHS);
  return V_FXXX_BHS;
end F_GET_SJ_FXXX_BH;

 从这里可以看出 虽然function实现的和原先的sql是一样的 ,但是每次循环改用function单独去计算 会比直接写在sql语句中节省很多时间(注:这个纯个人意见,个人对sql研究不是很深入,有更好的办法希望大家能回复我,不断学习中)

分享到:
评论

相关推荐

    数据库设计之递归树查询

    -- 递归子查询(递归部分) SELECT column1, column2, ... FROM cte_name -- 引用已定义的CTE JOIN table_name ON some_condition ) SELECT * FROM cte_name; ``` 四、实例解析 假设我们有一个`employees`表,...

    connect_by_prior_递归算法

    ### Oracle中的Connect By Prior递归算法详解 #### 一、Connect By Prior 子句概述 在Oracle数据库中,`Connect By Prior`子句是一种非常有用的工具,尤其在处理具有层次结构的数据时。它允许用户以一种简洁的方式...

    Oracle start with.connect by prior子句实现递归查询

    在Oracle数据库中,`Start With.Connect By Prior`子句是执行递归查询的一种强大工具,主要用于处理层次结构数据。这类数据通常存在于组织结构、产品分类、文件系统等场景中,通过递归查询可以方便地获取树状或层级...

    MySQL多种递归查询方法.docx

    在Oracle数据库中,递归查询可以通过`START WITH CONNECT BY PRIOR`语句实现。此语句允许用户按照树状结构来检索数据。 ##### 1. `START WITH CONNECT BY PRIOR`用法详解 **基本语法**: ```sql SELECT * FROM ...

    Oracle递归树形结构查询功能

    在进行递归查询优化时,要注意避免无限循环和性能问题,确保`CONNECT BY`条件正确无误,必要时还可以使用`CYCLE`子句来检测并处理循环引用。同时,合理利用索引可以显著提升查询效率。 总之,Oracle的递归树形结构...

    递归查询菜单树,支持mysql,oracle

    Oracle数据库也支持递归查询,但使用的是`CONNECT BY`语句。对于同样的`menus`表,Oracle的查询可能如下: ```sql SELECT id, parent_id, name, level as depth FROM menus START WITH parent_id IS NULL CONNECT ...

    ORACLE查询树型关系(connect_by_prior_start_with)

    使用 START WITH 和 CONNECT BY 子句可以实现 SQL 的层次查询,并且可以使用 SYS_CONNECT_BY_PATH 函数和 CONNECT_BY_ROOT、CONNECT_BY_ISLEAF、CONNECT_BY_ISCYCLE 等伪列函数来增强层次查询的能力。

    在db2和oracle中的对树的递归查询语句

    在Oracle中,对树的递归查询主要依赖于`CONNECT_BY`功能。`CONNECT_BY`是Oracle SQL的一个扩展,用于处理层次查询。它允许我们通过指定的连接条件来遍历层级数据,从而进行递归查询。例如,我们可以用以下方式查询一...

    Oracle中的树状查询(递归查询)

    在`Oracle中的树状查询(递归查询) - 鱼与飞鸟 - CSDNBlog.htm`这篇博客中,作者通过具体的实例详细讲解了如何在权限查询中使用递归查询,包括如何建立树形结构,以及如何避免无限递归等问题。 8. **补充资源** - ...

    10.2.0.3版本 with改造递归查询

    通过上述分析可以看出,在Oracle 10.2.0.3版本中使用WITH子句改造递归查询能够有效解决原本查询无法返回结果的问题。这种改造不仅提高了查询的灵活性,还使得整个查询逻辑更加清晰明了。对于处理复杂的层次结构数据...

    Oracle递归查询

    在Oracle数据库中,递归查询主要依赖于`START WITH`和`CONNECT BY PRIOR`两个关键语法。本文将详细介绍这些概念以及具体的使用方法。 #### 二、创建示例表 为了更好地理解Oracle中的递归查询,我们首先需要创建...

    Oracle的Connect By使用示例

    1. **Connect By**:用于指定层级关系中的父节点与子节点之间的连接条件。例如,在一个员工表中,如果想要查找所有下属及其下属的下属,可以使用`CONNECT BY PRIOR employee_id = manager_id`这样的表达式来定义上...

    Oracle递归SQL学习

    因此,合理设计表结构,例如使用自连接而不是递归,或者限制递归深度,对于优化查询性能至关重要。 至于Velocity模板语言,它并不支持递归渲染。这意味着在生成HTML或其他格式的输出时,如果需要递归地展示树结构,...

    dhtmlx tree 使用,与oracle递归查询的结合

    在Oracle中,进行递归查询通常使用的是`CONNECT BY`子句,它可以遍历层次结构数据,例如组织结构或具有层级关系的产品目录。递归查询允许我们从一个起点开始,通过指定的连接条件递归地获取所有相关的子节点。 **...

    oracle中connect-by-prior用法,实战解决日期分解问题.docx

    通过`CONNECT BY PRIOR`查询,我们可以获取整个组织架构,从根节点(如最高级别的部门)开始,递归地找出所有的子部门。 `LEVEL`关键字在处理树结构时也非常有用,它可以为每个节点分配一个层次级别,根节点的级别...

    在ORACLE、MSSQL、MYSQL中树结构表递归查询的实现.pdf

    CONNECT BY子句通常配合START WITH子句使用,其中START WITH指定了递归的起点,而CONNECT BY用于定义父子关系。CONNECT BY子句中的PRIOR关键字用于表示层级之间的连接,它指向前一个步骤得到的列值。例如,如果当前...

    Oracle递归查询start with connect by prior的用法

    在Oracle中,`START WITH` 和 `CONNECT BY` 是进行递归查询的关键字,它们允许我们从一个特定的根节点出发,沿着预定义的关系链接遍历整个树形结构。本文将深入探讨这两个关键字的用法,并通过实例来说明其在实际...

    Oracle_start_with_connect_by_prior_用法

    - 在使用`START WITH`和`CONNECT BY PRIOR`时,需要确保表中有合适的字段用于表示层级结构,如上面示例中的`PARENT_ID`字段。 - 当数据量较大时,递归查询可能会导致性能问题,因此需要谨慎使用。 - 使用这些特性时...

    Oracle 11GR2的递归WITH子查询方法

    与传统的`CONNECT BY`层次查询相比,递归WITH子查询提供了更直观的语法,更容易理解和调试,同时也支持更复杂的逻辑,比如在递归过程中进行计算、应用条件等。 总的来说,Oracle 11GR2的递归WITH子查询为处理层级...

Global site tag (gtag.js) - Google Analytics