2016-11-23 55 views
0

我有以下功能:如何避免在查詢中使用相同的函數多次,加快數據檢索

CREATE OR REPLACE FUNCTION IR.SRG(
    IR_item IN VARCHAR2, 
    IR_comp  VARCHAR2, 
    IR_locn  VARCHAR2, 
    IR_Type  VARCHAR2, 
    IR_fromdate DATE, 
    IR_tilldate DATE, 
) 
RETURN NUMBER DETERMINISTIC 
IS 
    IR_qty NUMBER; 
    myLocations sys.odcivarchar2list; --collection 

BEGIN 
    IF IR_locn = 'ALL' THEN 
     myLocations := SYS.ODCIVARCHAR2LIST('D2','D4','D5','D11'); 
    ELSE 
     myLocations := SYS.ODCIVARCHAR2LIST('D2'); 
    END IF; 

IF IR_TYPE  = 'O' then 
    SELECT SUM(QTY) 
    INTO IR_qty 
    FROM STOCK_LEDGER 
    WHERE ITEM_CODE = IR_item 
    AND LOCATION_CODE IN 
    (SELECT column_value FROM TABLE(myLocations) 
) 
    AND DOCUMENTDATE <= IR_TILLDATE 
    AND DOCUMENTDATE >= IR_FROMDATE; 
END IF; 

IF IR_TYPE  = 'C' then 
    SELECT SUM(QTY) 
    INTO IR_qty 
    FROM STOCK_LEDGER 
    WHERE ITEM_CODE = IR_item 
    AND LOCATION_CODE IN 
    (SELECT column_value FROM TABLE(myLocations) 
) 
    AND DOCUMENTDATE <= IR_TILLDATE 
    AND DOCUMENTDATE >= IR_FROMDATE 
    AND Some other conditions;; 
END IF; 

--Some Other Conditions 

RETURN (NVL (IR_QTY, 0)); 
EXCEPTION 
    WHEN ZERO_DIVIDE THEN 
    RETURN 0; 
END; 

這個功能是從查詢中多次調用。例如:

SELECT ITEM_CODE, 
     ITEM_NAME, 
     IR.SRG (IM.ITEM_CODE, 
       'Company1', 
       'ALL', 
       'O', 
       '01/01/2009', 
       '12/31/2010'), 
     IR.SRG (IM.ITEM_CODE, 
       'Company1', 
       'ALL', 
       'C', 
       '01/01/2009', 
       '12/31/2010') 
, -- Function Called with other Conditions     
    FROM ITEM_MASTER IM 

實施例,我有大約1500名的項目,所以對於在上面的查詢的每個項目,該功能被稱爲2次,一個用於'O'IR_Type,另一個用於'C'IR_Type。所以這個函數被稱爲3000次。我有8種不同類型的IR_Type和約15000項。它被稱爲120000次,這會使數據檢索速度減慢約2小時,這非常麻煩。

我需要幫助通過任何其他正確的方式檢索數據,這可以加快報告速度。

在此先感謝。

回答

1

看看你使用該功能還有多遠。

select item_code 
     ,item_name 
     ,(select sum(qty) 
      from stock_ledger 
     where item_code = im.item_code, 
      and location_code in ('D2', 'D4', 'D5', 'D11') 
      and documentdate <= to_date(:TO_DATE, 'MM/DD/YYYY') 
      and documentdate >= to_date(:FROM_DATE, 'MM/DD/YYYY')) as something1 
     ,ir.srg(im.item_code, 'Company1', 'ALL', 'C', '01/01/2009', '12/31/2010') 
     , -- Function Called with other Conditions     
    from item_master im 
+0

的參數是那些通過運行報告用戶通過動態。我無法對其進行硬編碼。 – user3625561

+0

這有什麼不同?我只是按照你的例子。使用綁定變量。 – Rene

+0

應該有其他的方式,比如做出多種功能或者使用一個程序或者包,我只是在猜測。 – user3625561

1

因爲不同的參數值,你應該把它叫做兩次,但你可以使用結果緩存以提高性能的。
https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:6978972926020

CREATE OR REPLACE FUNCTION IR.SRG(
IR_item IN VARCHAR2, 
IR_comp  VARCHAR2, 
IR_locn  VARCHAR2, 
IR_Type  VARCHAR2, 
IR_fromdate DATE, 
IR_tilldate DATE, 
) 
RETURN NUMBER DETERMINISTIC RESULT_CACHE IS 
    BEGIN 

     IF IR_locn = 'ALL' THEN 
     myLocations := SYS.ODCIVARCHAR2LIST('D2','D4','D5','D11'); 
    ELSE 
     myLocations := SYS.ODCIVARCHAR2LIST('D2'); 
    END IF; 

IF IR_TYPE  = 'O' then 
    SELECT SUM(QTY) 
    INTO IR_qty 
    FROM STOCK_LEDGER 
    WHERE ITEM_CODE = IR_item 
    AND LOCATION_CODE IN 
    (SELECT column_value FROM TABLE(myLocations) 
) 
    AND DOCUMENTDATE <= IR_TILLDATE 
    AND DOCUMENTDATE >= IR_FROMDATE; 
END IF; 

IF IR_TYPE  = 'C' then 
    SELECT SUM(QTY) 
    INTO IR_qty 
    FROM STOCK_LEDGER 
    WHERE ITEM_CODE = IR_item 
    AND LOCATION_CODE IN 
    (SELECT column_value FROM TABLE(myLocations) 
) 
    AND DOCUMENTDATE <= IR_TILLDATE 
    AND DOCUMENTDATE >= IR_FROMDATE 
    AND Some other conditions;; 
END IF; 

--Some Other Conditions 

RETURN (NVL (IR_QTY, 0)); 
EXCEPTION 
    WHEN ZERO_DIVIDE THEN 
    RETURN 0; 
END; 
+0

性能顯着提高!讓我驗證數據並回復給您。 – user3625561

相關問題