2015-10-13 155 views
1

我有一块sql程序外运行非常流畅。当我把sql块放在过程中以返回ref_cursor时,该过程花了相当长的时间来执行ref_cursor。Oracle Procedure需要很长时间才能运行,但直接sql运行很快

与数据库管理员的帮助下,我们实现了数据库配置文件,它的工作极大地加快程序,但随后在那个特定的程序的任何微小的变化使它就会失控。我不确定是什么问题..我用尽了选择。我应该如何解决这个奇怪的问题?

预先感谢您。

编辑..这里是查询

with query_ownership as (SELECT leeo.legal_entity_id, 
          leeo.parent_le_id, 
          SUM(leeo.effective_ownership) ownership_percent 
         FROM data_ownership leeo 
        WHERE leeo.start_date <= 
          to_date('12/31/2012','mm/dd/yyyy') 
         AND ((leeo.end_date < &lvTaxYearDate and leeo.end_date > &lvTaxYearBeginDate) 
          to_date('12/31/2012','mm/dd/yyyy') OR 
          leeo.end_date IS NULL) 
         and leeo.stock_type in ('E') 
        GROUP BY leeo.legal_entity_id, leeo.parent_le_id 
        HAVING SUM(leeo.effective_ownership) > 0 
), 
query_branches as (SELECT b.branch_id  as legal_entity_id, 
          b.legal_entity_id as perent_le_id, 
          1.00    as ownership_percent 
         FROM company_branches b 
        WHERE b.tax_year = 2012), 
child_query as (select * from query_ownership 
        UNION 
      select * from query_branches), 
parent_query as (select * from query_ownership 
        UNION 
      select * from query_branches),          
inner_query as (SELECT rownum      as sortcode, 
        -level      as lvl, 
        child_query.parent_le_id, 
        child_query.legal_entity_id, 
        child_query.ownership_percent 
       FROM child_query 
      START WITH child_query.legal_entity_id = 'AB1203' 
      CONNECT BY NOCYCLE PRIOR child_query.legal_entity_id = 
         child_query.parent_le_id 
        AND child_query.ownership_percent >= 0.01 
        and level = 0 
      UNION 
      SELECT rownum as sortcode, 
        level - 1 as lvl, 
        parent_query.parent_le_id, 
        parent_query.legal_entity_id, 
        parent_query.ownership_percent 
       FROM parent_query 
      START WITH parent_query.legal_entity_id = 'AB1203' 
      CONNECT BY NOCYCLE 
      PRIOR parent_query.parent_le_id = 
         parent_query.legal_entity_id 
        AND parent_query.ownership_percent >= 0.01) 
        ,ownership_heirarchy as (
       SELECT max(inner_query.sortcode) as sortcode, 
      max(inner_query.lvl) as lvl, 
      inner_query.parent_le_id, 
      inner_query.legal_entity_id, 
      inner_query.ownership_percent from inner_query 
    GROUP BY inner_query.parent_le_id, 
       inner_query.legal_entity_id, 
       inner_query.ownership_percent 
      ) 
       ,goldList as (
SELECT lem2.legal_entity_id from ownership_heirarchy, 
    company_entity_year lem1, 
    company_entity_year lem2 
WHERE ownership_heirarchy.parent_le_id = lem2.legal_entity_id 
AND lem2.tax_year = 2012 

AND ownership_heirarchy.legal_entity_id = lem1.legal_entity_id 
AND lem1.tax_year = 2012 
AND lem1.legal_entity_type <> 'EXT' 
AND lem1.non_legal_entity_flag is null 
AND lem2.legal_entity_type <> 'EXT' 
AND lem2.non_legal_entity_flag is null 
and TRIM(lem2.alt_tax_type) is null 
and UPPER(lem2.tax_type) in ('DC', 'DPS', 'TXN') 
), 
fulllist as (
     select * from goldList 
     union 
     select gc.parent_le_id from company_entity_year e,  consolidation_group gc 
where e.LEGAL_ENTITY_ID = 'AB1203' and e.tax_year = 2012 
and e.TAX_CONSOLIDATION_GRP = gc.group_id 
     union 
     select e.leid from vdst_entity e where e.TAX_YEAR = 2012 
     and e.ALT_TAX_TYPE in (3,8) 
     and e.LEID = 'AB1203' 
) 

    select distinct dc.dcn_id  as dcnId, 
     dc.dcn_name as dcnName, 
     dy.dcn_year_id dcnYearId, 
     ty.tax_year_id taxYearId, 
     ty.tax_year taxYear 
    from company_dcn dc, company_dcn_year dy, company_tax_year ty 
    where dc.dcn_id = dy.dcn_id 
    and dy.year_id = ty.tax_year_id 
    and ty.tax_year = 2012 
    and dc.leid in (
     select * from fulllist 
        ); 
+0

问题很明显就在存储过程的第17行。 – mustaccio

+0

更新了问题以包含有问题的查询。 –

+0

听起来好像对于带有文字的查询(“在流程之外平滑”)和绑定变量(在PL/SQL中)可能有不同的执行计划。 – mustaccio

回答

0

首先,确保统计信息是最新的运行DBMS_STATS.GATHER_TABLE_STATS用于查询中涉及的每个表。接下来,获取具有不同参数值的查询计划 - 完全可能的是,参数的改变可能会使计划变得更好或更糟。鉴于您没有向我们展示关于查询,程序和涉及的表格的信息,因此无法更具体。

祝你好运。

0

找出执行计划的一部分,是造成问题。有几种方法可以做到这一点:

  1. 使用DBMS_XPLAN找到一个好的和坏的计划。使用explain plan for ...select * from table(dbms_xplan.display);在会话中找到好计划。使用dbms_xplan.display_cursor(sql_id => 'some sql_id')找到坏计划。比较计划并寻找差异。这可能非常困难,因为通常无法确定执行计划的哪些部分很慢。如果幸运的话,只会有一个区别,那么显然这个区别就是问题所在。
  2. 使用DBMS_SQLTUNE.REPORT_SQL_MONITOR找到什么计划的一部分是坏的。运行错误的查询并使用SQL Monitoring来查明执行计划中的哪个操作是坏的。该报告显示哪些操作时间最长,哪些基数估计值最多。重点放在缓慢的部分,以及计划的第一步,估计和实际之间存在巨大的基数差异。
  3. 看轮廓提示,找出了Oracle如何修复坏的计划。配置文件是帮助推动优化程序做出正确决定的提示集合。这些提示可能会告诉你问题是什么。例如,如果其中一个提示是OPT_ESTIMATE(JOIN (A B) SCALE_ROWS=100),该配置文件告诉优化器将基数估计值提高100倍。您可以通过在查询中包含该提示或通过创建和锁定假表统计来重新创建相同的影响。使用Kerry Osborne的this process来查找配置文件提示。

无论哪种方式,该过程可能是困难和耗时的。尽量缩小查询的范围。调整97行查询可能几乎是不可能的。有可能只有一个根本问题,但是这个问题改变了很多执行计划,看起来有十几个问题。

这些步骤只能帮你找出问题所在。解决它可能是一个完整的其他问题和答案。

相关问题