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

相关问题