Plsql 使用ROWID的merge语句

Plsql 使用ROWID的merge语句,plsql,merge,lookup,Plsql,Merge,Lookup,我需要在事实表上填充3个外部维度键。我已经尝试使用下面的merge语句(使用ROWID)来填充这三个字段,但是它需要15个多小时才能运行,所以我想知道我可以采取哪些更快的替代方法?事实表大约有180万条记录,其中一个维度(查找函数3)是900K条记录 我创建了3个查找函数来返回维度键。这些函数中的每一个都来自事实表上的一个字段,并且必须连接到2或3个表才能返回dim键。我已经为连接中的字段编制了索引,并且每个字段的解释计划看起来都很合理,但是仍然需要非常长的时间才能运行。每次刷新数据时,我都需要

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

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

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
--查找功能1 --索引列:pr.PRODUCT\U 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';
--查找功能2 --索引列:addr.EXTRNL\u CUST\u ID,addr.PSTL\u 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;
--查找功能3 --索引列:ccv.VAL_1_ID、ac.IMS_ID、ac.ACTIVE_标志

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'

不要使用PL/SQL函数。您可以避免开销。
只需使用相关子查询进行简单更新:

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小时。

我不明白你为什么在这里使用
合并。当匹配时,
分支上只有代码,因此可以使用更新。此外-此语句更新事实表的每一行,这意味着您要进行540万个过程调用(380万个)和180万个行更新。那是你想要的吗?