2017-01-02 6 views
0

У меня есть 3 ключа внешнего измерения. Мне нужно заполнить таблицу фактов. Я попытался использовать следующий оператор слияния (используя ROWID), чтобы заполнить эти три поля, однако для этого требуется более 15 часов, поэтому мне интересно, какие альтернативные подходы я могу предпринять, что будет быстрее? Таблица фактов составляет около 1,8 миллиона записей, а одно из измерений (функция поиска 3) - 900 тыс. Записей.слияния с использованием ROWID

Я создал 3 функции поиска, чтобы вернуть размерные ключи. Каждая из этих функций переходит из поля таблицы фактов и должна присоединиться к 2 или 3 таблицам, чтобы вернуть тусклые клавиши. Я проиндексировал поля в соединениях, и план объяснения для каждого из них выглядит разумным, однако он все еще занимает очень много времени для запуска. Мне нужно будет повторно заполнить эти тусклые клавиши каждый раз, когда данные будут обновлены, потому что, к сожалению, исходные данные усекаются и перезагружаются каждый раз. Любое понимание было бы высоко оценено!

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 функция 1 --columns индексируются: 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 Функция 2 --columns индексируются: 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 function 3 - проиндексированы колонки: 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

Я не понимаю, почему вы используете «MERGE» здесь. У вас есть код в ветке 'WHEN MATCHED', поэтому вы можете просто использовать UPDATE. Также - этот оператор обновляет каждую строку вашей таблицы фактов, что означает, что вы делаете 5,4 миллиона вызовов процедур (3 * 1,8 миллиона) и 1,8 миллиона обновлений строк. Это то, что вы хотели? –

ответ

0

Не используйте функции PL/SQL. Вы избегаете накладных расходов context switch.
Просто сделайте простое обновление с помощью коррелированных подзапросов:

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' 
) 

Я верю, это будет по крайней мере 40 ~ 50 раз быстрее
-> да, в 50 раз, это не ошибка - в 50 раз, что составляет 5000% !!!
1 час вместо 50 часов.