2015-10-13 167 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行查詢可能幾乎是不可能的。有可能只有一個根本問題,但是這個問題改變了很多執行計劃,看起來有十幾個問題。

這些步驟只能幫你找出問題所在。解決它可能是一個完整的其他問題和答案。

相關問題