You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Each month, there will be about 24 million rows of customer spending data.
My task is to generate a list of CIFs where the total volatility for a user-specified column (pi_colName) exceeds the user-specified threshold (pi_min_volatility) from a reference date (pi_rdate) to the specified date (pi_date).
Requirements:
The query must execute in under 1 minute.
Indexing is not allowed because it would require too much memory to store indexes for the new data added each month.
I am using Oracle Database.
Thank you very much for your help!
Here is my code, but it takes around 2 minutes to run:
PROCEDURE VOLATILITY_REPORT_041_DBTK
( pi_colName INVARCHAR2,
pi_date INVARCHAR2,
pi_rdate INVARCHAR2,
pi_branch INVARCHAR2,
pi_min_volatility INNUMBER,
PI_Start INNUMBER,
PI_End INNUMBER,
-- PARAM OUT
PO_TotalRow OUT NUMBER,
-- DEFAULT
PO_ErrorCode OUT VARCHAR2,
PO_ErrorDesc OUT VARCHAR2,
PO_Cursor OUT SYS_REFCURSOR
) AS
l_upper_colNam VARCHAR2(100);
l_sql CLOB;
l_count_sql CLOB;
l_exits NUMBER;
table_exists NUMBER;
BEGINSELECTCOUNT(*) INTO table_exists
FROM USER_TABLES
WHERE TABLE_NAME ='DAT_VOLATILITY_REPORT_041_DBTK_TEMP';
IF table_exists >0 THEN
EXECUTE IMMEDIATE 'DROP TABLE DAT_VOLATILITY_REPORT_041_DBTK_TEMP';
END IF;
l_sql :=' CREATE TABLE DAT_VOLATILITY_REPORT_041_DBTK_TEMP AS WITH FULL_THIS_TERM_DAT AS ( SELECT A.CIF, A.BRANCH, A.ACCTNO, A.CURTYPE, A.E_SECTOR, A.UNIT, NVL(TO_NUMBER(A.'|| l_upper_colNam ||'), 0) AS THIS_TERM_DAT FROM VOLATILITY_REPORT_041_DBTK A WHERE A.PERIOD = TO_DATE('''|| pi_date ||''', ''DD/MM/YYYY'') AND ('|| CASE WHEN pi_branch IS NULLOR pi_branch ='' THEN '1=1' ELSE 'A.BRANCH = '''|| pi_branch ||'''' END ||') ), FULL_PREV_TERM_DAT AS ( SELECT B.CIF, B.BRANCH, B.ACCTNO, NVL(TO_NUMBER(B.'|| l_upper_colNam ||'), 0) AS PREV_TERM_DAT FROM VOLATILITY_REPORT_041_DBTK B WHERE B.PERIOD = TO_DATE('''|| pi_rdate ||''', ''DD/MM/YYYY'') AND ('|| CASE WHEN pi_branch IS NULLOR pi_branch ='' THEN '1=1' ELSE 'B.BRANCH = '''|| pi_branch ||'''' END ||') ), THIS_TERM_DAT AS ( SELECT CIF, SUM(THIS_TERM_DAT) AS THIS_TERM_DAT FROM FULL_THIS_TERM_DAT GROUP BY CIF ), PREV_TERM_DAT AS ( SELECT CIF, SUM(PREV_TERM_DAT) AS PREV_TERM_DAT FROM FULL_PREV_TERM_DAT GROUP BY CIF ), VARIATION AS ( SELECT KN.CIF, NVL(KN.THIS_TERM_DAT, 0) AS TONG_THIS_TERM_DAT, NVL(KT.PREV_TERM_DAT, 0) AS TONG_PREV_TERM_DAT, ABS(NVL(KN.THIS_TERM_DAT, 0) - NVL(KT.PREV_TERM_DAT, 0)) AS pi_min_volatility FROM THIS_TERM_DAT KN LEFT JOIN PREV_TERM_DAT KT ON KN.CIF = KT.CIF WHERE ABS(NVL(KN.THIS_TERM_DAT, 0) - NVL(KT.PREV_TERM_DAT, 0)) >= NVL('|| pi_min_volatility ||', 0) ), DATA_CHI_TIET AS ( SELECT A.CIF, A.BRANCH, A.ACCTNO, A.CURTYPE, A.E_SECTOR, A.UNIT, NVL(THIS_TERM_DAT, 0) THIS_TERM_DAT, NVL(PREV_TERM_DAT, 0) PREV_TERM_DAT, ABS(NVL(THIS_TERM_DAT, 0) - NVL(PREV_TERM_DAT, 0)) AS pi_min_volatility FROM FULL_THIS_TERM_DAT A LEFT JOIN FULL_PREV_TERM_DAT B ON A.CIF = B.CIF AND A.ACCTNO = B.ACCTNO WHERE A.CIF IN (SELECT CIF FROM VARIATION) ) SELECT D.*, ROW_NUMBER() OVER (ORDER BY D.pi_min_volatility DESC, D.CIF) AS RN FROM DATA_CHI_TIET D';
DBMS_OUTPUT.put_line(l_sql);
EXECUTE IMMEDIATE l_sql;
OPEN PO_Cursor FOR 'SELECT * FROM DAT_VOLATILITY_REPORT_041_DBTK_TEMP WHERE RN BETWEEN '||PI_Start||' AND '||PI_End;
l_count_sql :='SELECT COUNT(*) FROM DAT_VOLATILITY_REPORT_041_DBTK_TEMP';
EXECUTE IMMEDIATE l_count_sql INTO PO_TotalRow;
-- EXECUTE IMMEDIATE 'DROP TABLE DAT_VOLATILITY_REPORT_041_DBTK_TEMP';
PO_ErrorCode :=200;
PO_ErrorDesc :='SUCCESS';
EXCEPTION
WHEN OTHERS THEN
PO_ErrorCode := SQLCODE;
PO_ErrorDesc := SQLERRM;
END VOLATILITY_REPORT_041_DBTK;
The text was updated successfully, but these errors were encountered:
Can someone help me solve this problem?
Requirements:
Thank you very much for your help!
Here is my table
Here is my code, but it takes around 2 minutes to run:
The text was updated successfully, but these errors were encountered: