Ho questa domanda:
UPDATE (
SELECT h.valid_through_dt, h.LAST_UPDATE_TMSTMP
FROM ETL_FEE_SCH_TMP d, FEE_SCHEDULE_HISTORICAL h
WHERE h.FUND_ID = d.FUND_ID
AND h.FEETYPE_NAME = d.FEETYPE_NAME
AND h.BREAKPOINT_TYPE = d.BREAKPOINT_TYPE
AND h.BREAKPOINT_QTY = d.BREAKPOINT_QTY
AND h.LOW_BREAKPOINT_AMT = d.LOW_BREAKPOINT_AMT
AND h.VALID_THROUGH = TO_DATE ('31-DEC-9999', 'dd-mon-yyyy')
AND h.universe = 'DC'
AND h.universe = d.universe
AND EXISTS
(
SELECT 1
FROM FEE_SCHEDULE s
WHERE s.FUND_ID = h.FUND_ID
AND s.FEETYPE_NAME = h.FEETYPE_NAME
AND s.BREAKPOINT_TYPE = h.BREAKPOINT_TYPE
AND s.BREAKPOINT_QTY = h.BREAKPOINT_QTY
AND s.LOW_BREAKPOINT_AMT = h.LOW_BREAKPOINT_AMT
AND s.universe = 'DC'
)
) updateTable
SET updateTable.VALID_THROUGH = (SYSDATE - 1),
updateTable.LAST_UPDATE_TMSTMP = SYSTIMESTAMP;
Il problema che sto riscontrando è che questa query richiede molto tempo per essere eseguita. Non so se sia possibile eseguirlo in parallelo, o sarebbe più semplice aggiornare un cursore in una funzione di pipeline.
Che cosa suggeriresti?
Queste sono tutte le informazioni che ritengo rilevanti.
Questo è il piano di esecuzione della selezione interna:
Execution Plan
----------------------------------------------------------
Plan hash value: 57376096
---------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes| Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 306 | 8427 (1)| 00:01:42 |
| 1 | NESTED LOOPS | | | | | |
| 2 | NESTED LOOPS | | 1 | 306| 8427 (1)| 00:01:42 |
| 3 | MERGE JOIN CARTESIAN | | 1 | 192| 8426 (1)| 00:01:42 |
|* 4 | INDEX RANGE SCAN | SYS_C000666 | 1 | 96| 2 (0)| 00:00:01 |
| 5 | BUFFER SORT | | 3045K| 278M| 8425 (1)| 00:01:42 |
| 6 | SORT UNIQUE | | 3045K| 278M| 8425 (1)| 00:01:42 |
|* 7 | TABLE ACCESS FULL | FEE_SCHEDULE | 3045K| 278M| 8425 (1)| 00:01:42 |
|* 8 | INDEX RANGE SCAN | FEE_SCHDL_IDX1 | 1 | | 1 (0)| 00:00:01 |
|* 9 | TABLE ACCESS BY INDEX ROWID| FEE_SCHEDULE_HISTORICAL | 1 | 114 | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("D"."UNIVERSE"='DC')
7 - filter("S"."UNIVERSE"='DC')
8 - access("H"."UNIVERSE"='DC' AND "S"."FUND_ID"="H"."FUND_ID" AND
"S"."FEETYPE_NAME"="H"."FEETYPE_NAME" AND
"S"."BREAKPOINT_TYPE"="H"."BREAKPOINT_TYPE" AND
"S"."BREAKPOINT_QTY"="H"."BREAKPOINT_QTY" AND
"S"."LOW_BREAKPOINT_AMT"="H"."LOW_BREAKPOINT_AMT")
filter("H"."FUND_ID"="D"."FUND_ID" AND
"H"."FEETYPE_NAME"="D"."FEETYPE_NAME" AND
"H"."BREAKPOINT_TYPE"="D"."BREAKPOINT_UNIT_TY
Dati della tabella:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
UNIVERSE|FUND_ID |FEETYPE_NAME |BREAKPOINT_TYPE|BREAKPOINT_QTY|LOW_BREAKPOINT_AMT|HIGH_BREAKPOINT_AMT|FEE_PCT|FEE_SCHDL_SEQ_ID|GROUP_ID|LAST_UPDATE_TMSTMP |VALID_FROM|VALID_THROUGH|INSERT_TMSTMP |JOB_ID|
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
DC |DC9ZTPLPHO|DeferLoad |Percentage |4 |10000 |300000 |3.14 |780250 |null |1/4/2012 3:59:54 PM|6/23/2012 |12/31/9999 |1/5/2011 3:59:54 PM|666 |
DC |DCE86Y8XFU|RedemptionFee|Percentage |9 | 100 |100500 |7.67 |780251 |null |6/4/2012 4:49:54 PM|11/12/2011|12/31/9999 |8/17/2011 2:00:54 PM|666 |
DC |DCAYL0KONA|FrontLoad |Percentage |2 |50000 |601500 |5.00 |780252 |null |4/25/2012 4:49:54 PM|8/2/2012 |12/31/9999 |12/19/2012 9:59:00 PM|666 |
DC |DC9ZTPLPHO|DeferLoad |Percentage |7 |80000 |900000 |2.24 |780252 |null |4/25/2012 4:49:54 PM|8/2/2012 |12/31/9999 |12/19/2012 9:59:00 PM|666 |
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Questa è la sceneggiatura della tabella storica:
CREATE TABLE FEE_SCHEDULE_HISTORICAL
(
UNIVERSE VARCHAR2(2 BYTE) NOT NULL,
FUND_ID VARCHAR2(10 BYTE) NOT NULL,
FEETYPE_NAME VARCHAR2(75 BYTE),
BREAKPOINT_TYPE VARCHAR2(50 BYTE),
BREAKPOINT_QTY VARCHAR2(10 BYTE),
LOW_BREAKPOINT_AMT NUMBER(19,6),
HIGH_BREAKPOINT_AMT NUMBER(19,6),
FEE_PCT NUMBER(19,6),
FEE_SCHDL_SEQ_ID NUMBER NOT NULL,
GROUP_ID NUMBER,
LAST_UPDATE_TMSTMP DATE NOT NULL,
VALID_FROM DATE NOT NULL,
VALID_THROUGH DATE NOT NULL,
INSERT_TMSTMP DATE NOT NULL,
JOB_ID NUMBER NOT NULL
);
CREATE UNIQUE INDEX FEE_SCHDL_PK ON FEE_SCHEDULE_HISTORICAL(FEE_SCHDL_SEQ_ID);
CREATE UNIQUE INDEX FEE_SCHDL_HST_IDX ON FEE_SCHEDULE_HISTORICAL (
UNIVERSE,
FUND_ID,
FEETYPE_NAME,
BREAKPOINT_TYPE,
BREAKPOINT_QTY,
LOW_BREAKPOINT_AMT,
VALID_FROM,
JOB_ID
)
CREATE INDEX FEE_SCHEDULE_HST_IDX2 ON FEE_SCHEDULE_HISTORICAL(LAST_UPDATE_TMSTMP)
CREATE INDEX FEE_SCHEDULE_HST_IDX3 ON FEE_SCHEDULE_HISTORICAL(VALID_THROUGH)
ALTER TABLE FEE_SCHEDULE_HISTORICAL ADD (
CONSTRAINT FEE_SCHDL_PK
PRIMARY KEY
(FEE_SCHDL_SEQ_ID)
);
Questa è l'altra tabella:
CREATE TABLE FEE_SCHEDULE
(
UNIVERSE VARCHAR2(2 BYTE) NOT NULL,
FUND_ID VARCHAR2(10 BYTE) NOT NULL,
FEETYPE_NAME VARCHAR2(75 BYTE),
BREAKPOINT_TYPE VARCHAR2(50 BYTE),
BREAKPOINT_QTY VARCHAR2(10 BYTE),
LOW_BREAKPOINT_AMT NUMBER(19,6),
HIGH_BREAKPOINT_AMT NUMBER(19,6),
FEE_PCT NUMBER(19,6),
JOB_RUN_ID NUMBER NOT NULL,
FILE_DATE DATE NOT NULL,
CYCLE_DATE DATE NOT NULL
)
La tabella temporanea è il risultato di FEE_SCHEDULE_HISTORICAL meno FEE_SCHEDULE
..AND EXISTS (SELECT NULL..
restituirebbe sempre falso? Questo - ..AND NOT EXISTS (SELECT 1..
avrebbe più senso ??
SELECT NULL...
è chiaramente confuso e non dovrebbe essere usato (a meno che non si stia utilizzando a UNION
).
fee_schedule (universe, fund_id, feetype_name, breakpoint_type, breakpoint_qty, low_breakpoint_amt)
. Forse uno su universe, fund_id
è già abbastanza buono da trasformare quell'FTS in una scansione di indice.