使用ROWID合并语句

时间:2017-01-02 19:14:33

标签: plsql merge lookup

我需要在事实表上填充3个外部维度键。我已经尝试使用以下合并语句(使用ROWID)来填充这三个字段,但是它运行需要超过15个小时,所以我想知道我可以采取哪种替代方法会更快?事实表大约有180万条记录,其中一个维度(查找功能3)是900K记录。

我创建了3个查找函数来返回维度键。这些函数中的每一个都来自事实表上的字段,并且必须连接到2或3个表以返回调暗键。我已经为连接中的字段编制索引,并且每个连接的解释计划看起来都很合理,但是它仍然需要很长时间才能运行。每次刷新数据时,我都需要重新填充这些暗淡的键,因为不幸的是每次都会截断并重新加载源数据。任何见解将不胜感激!

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;

- 查找功能1 --columns索引:pr.PRODUCT_SKU

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'

- 查找功能2 --columns索引:addr.EXTRNL_CUST_ID,addr.PSTL_CD

{{1}}

- 查找功能3 --columns索引:ccv.VAL_1_ID,ac.IMS_ID,ac.ACTIVE_FLAG

{{1}}

1 个答案:

答案 0 :(得分: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小时。