2017-01-02 3 views
0

Ich habe 3 ausländische Dimension Schlüssel, die ich auf einer Faktentabelle ausfüllen muss. Ich habe versucht, die folgende Merge-Anweisung (mit ROWID) zu verwenden, um diese drei Felder zu füllen, jedoch dauert es mehr als 15 Stunden zu laufen, also frage ich mich, welche alternativen Ansätze ich nehmen kann, die schneller sein werden? Die Faktentabelle ist etwa 1,8 Millionen Datensätze und eine der Dimensionen (Suchfunktion 3) ist 900K Datensätze.Merge-Anweisung mit ROWID

Ich habe 3 Suchfunktionen erstellt, um die Dimensionsschlüssel zurückzugeben. Jede dieser Funktionen geht von einem Feld in der Faktentabelle aus und muss zu 2 oder 3 Tabellen zusammengefügt werden, um die dunklen Schlüssel zurückzugeben. Ich habe die Felder in den Joins indiziert und der EXPLAIN-Plan für jeden von ihnen sieht vernünftig aus, aber es dauert immer noch extrem lange, um zu laufen. Ich werde diese Dim-Keys jedes Mal erneut auffüllen müssen, wenn die Daten aktualisiert werden, da die Quelldaten leider jedes Mal abgeschnitten und neu geladen werden. Jeder Einblick würde sehr geschätzt werden!

MERGE INTO 
(SELECT PRODUCT_DIM_KEY, TERRITORY_DIM_KEY, ACCOUNT_DIM_KEY , CUST_ID , PD_DT, DEXCOM_SKU_CD, ROWID rid 
FROM FACT_TABLE 
) ft1 
USING (select ROWID as rid 
FROM FACT_TABLE 
) ft2 
ON (ft1.rid = ft2.rid) 
--join using ROWID 
WHEN MATCHED THEN UPDATE 
SET ft1.PRODUCT_DIM_KEY = PRODUCT_DIM_LOOKUP_FUNCTION(ft1.DEXCOM_SKU_CD), 
--lookup function 1 
ft1.TERRITORY_DIM_KEY = TERRITORY_DIM_LOOKUP_FUNCTION(ft1.CUST_ID), 
--lookup function 2 
ft1.ACCOUNT_DIM_KEY = ACCOUNT_DIM_LOOKUP_FUNCTION(ft1.CUST_ID) 
--lookup function 3 

--Lookup Funktion 1 --columns indexiert: pr.PRODUCT_SKU

BEGIN 
    SELECT PRODUCT_DIM_KEY INTO v_dim_id 
    FROM PRODUCT_DIM pr 
    WHERE pr.PRODUCT_SKU   = p_product_code 
    AND pr.PRODUCT_DELETED_FLAG = 'N'; 

--Lookup Funktion 2 --columns indexiert: addr.EXTRNL_CUST_ID, addr.PSTL_CD

BEGIN 
    SELECT TERRITORY_DIM_KEY 
    INTO v_dim_id 
    FROM ADDR_DIM addr, 
     ZIP_CODE_DIM zip, 
     TERRITORY_DIM terr 
WHERE  p_hcp_code = addr.EXTRNL_CUST_ID 
     AND addr.BEST_REC_IND = 1 
     AND SUBSTR (addr.PSTL_CD, 1, 5) = zip.ZIP_CODE 
     AND zip.ACTIVE_FLAG = 'Y' 
     AND terr.TERRITORY_CODE = zip.TERRITORY_CODE; 

--Lookup-Funktion 3 - Spalten indiziert: CCV.VAL_1_ID, AC.IMS_ID, AC.ACTIVE_FLAG

BEGIN 
SELECT ACCOUNT_DIM_KEY 
    INTO v_dim_id 
    FROM CCV_DIM ccv, 
     ACCOUNT_DIM ac 
WHERE  p_hcp_code = ccv.CUST_ID 
     AND ccv.SCNDY_ID_TYP_XID = 202325 
     AND ccv.VAL_1_ID = ac.IMS_ID 
     AND ac.ACTIVE_FLAG = 'Y' 
+0

Ich verstehe nicht, warum Sie hier eine 'MERGE' verwenden. Sie haben nur Code auf dem "WHEN MATCHED" Zweig, so dass Sie einfach ein UPDATE verwenden können. Außerdem - diese Anweisung aktualisiert jede einzelne Zeile Ihrer Faktentabelle, was bedeutet, dass Sie 5,4 Millionen Prozeduraufrufe (3 * 1,8 Millionen) und 1,8 Millionen Zeilenaktualisierungen durchführen. War das was du wolltest? –

Antwort

0

Verwenden Sie keine PL/SQL-Funktionen. Sie vermeiden context switch Overhead.
tun nur ein einfaches Update mit korrelierten Unterabfragen:

UPDATE FACT_TABLE ft1 
SET 
ft1.PRODUCT_DIM_KEY = (
    SELECT PRODUCT_DIM_KEY FROM PRODUCT_DIM pr 
    WHERE pr.PRODUCT_SKU   = ft1.DEXCOM_SKU_CD 
     AND pr.PRODUCT_DELETED_FLAG = 'N' 
), 
ft1.TERRITORY_DIM_KEY = (
     SELECT TERRITORY_DIM_KEY 
     FROM ADDR_DIM addr, ZIP_CODE_DIM zip, TERRITORY_DIM terr 
     WHERE  ft1.CUST_ID = addr.EXTRNL_CUST_ID 
      AND addr.BEST_REC_IND = 1 
      AND SUBSTR (addr.PSTL_CD, 1, 5) = zip.ZIP_CODE 
      AND zip.ACTIVE_FLAG = 'Y' 
      AND terr.TERRITORY_CODE = zip.TERRITORY_CODE 
), 
ft1.ACCOUNT_DIM_KEY = (
     SELECT ACCOUNT_DIM_KEY 
     FROM CCV_DIM ccv, ACCOUNT_DIM ac 
     WHERE  ft1.CUST_ID = ccv.CUST_ID 
      AND ccv.SCNDY_ID_TYP_XID = 202325 
      AND ccv.VAL_1_ID = ac.IMS_ID 
      AND ac.ACTIVE_FLAG = 'Y' 
) 

ich glaube mindestens 40 ~ 50-mal schneller sein
-> ja, 50-mal, es ist kein Fehler - 50-mal ist es 5000% !!!
1 Stunde statt 50 Stunden.