问题描述
我正在尝试使用 oracle 中的合并语句进行更新,源有 20M 条记录,目标有 118 M 条记录。合并的执行需要很长时间。下面列出的是我的合并声明。我还放置了解释计划的屏幕截图以供参考。
MERGE
/*+ parallel(A,10) enable_parallel_dml*/
INTO
(
SELECT
PAY_RANGE_START_DATE_KEY,AA_PERSON_NATURAL_KEY,AA_PERSON_ASSIGNMENT_KEY,SCHEDULE_LINE_ID,SRC_CREATED_DATE,SRC_LAST_UPDATE_DATE
FROM
EDWFIN.PSP_LABOR_SCHD_DAY_F_ROLLUP
)
A USING
(
SELECT
pay_range_start_date_key,aa_person_natural_key,aa_person_assignment_key,schedule_line_id,MAX(src_created_date) src_created_date,MAX(src_last_update_date) src_last_update_date
FROM
edwfin.psp_labor_schd_day_f_rollup_frs_356
GROUP BY
pay_range_start_date_key,schedule_line_id
)
B ON
(
A.PAY_RANGE_START_DATE_KEY = B.PAY_RANGE_START_DATE_KEY AND
A.AA_PERSON_NATURAL_KEY = B.AA_PERSON_NATURAL_KEY AND
A.AA_PERSON_ASSIGNMENT_KEY = B.AA_PERSON_ASSIGNMENT_KEY AND
A.SCHEDULE_LINE_ID = B.SCHEDULE_LINE_ID
)
WHEN MATCHED THEN
UPDATE
SET
A.SRC_CREATED_DATE = B.SRC_CREATED_DATE,A.SRC_LAST_UPDATE_DATE = B.SRC_LAST_UPDATE_DATE
WHERE
A.SRC_CREATED_DATE <> B.SRC_CREATED_DATE
OR A.SRC_LAST_UPDATE_DATE <> B.SRC_LAST_UPDATE_DATE;
COMMIT;
解决方法
如果这是一次性交易,我会简单地使用 CTAS 或 Insert... 作为 select... 重新创建表,然后再添加索引。您已经在使用并行执行; CTAS 或 Insert ... as select... 可以做直接路径。
select 语句看起来像这样。我还假设所有键列都定义为 NOT NULL。
select < all columns from A,except SRC_CREATED_DATE and SRC_LAST_UPDATE_DATE >,case
when B.PAY_RANGE_START_DATE_KEY is null
then A.SRC_CREATED_DATE
else
case
when A.SRC_CREATED_DATE <> B.SRC_CREATED_DATE OR A.SRC_LAST_UPDATE_DATE <> B.SRC_LAST_UPDATE_DATE
then B.SRC_CREATED_DATE
else A.SRC_CREATED_DATE
end
end SRC_CREATED_DATE,case
when B.PAY_RANGE_START_DATE_KEY is null
then A.SRC_LAST_UPDATE_DATE
else
case
when A.SRC_CREATED_DATE <> B.SRC_CREATED_DATE OR A.SRC_LAST_UPDATE_DATE <> B.SRC_LAST_UPDATE_DATE
then B.SRC_LAST_UPDATE_DATE
else A.SRC_LAST_UPDATE_DATE
end
end SRC_LAST_UPDATE_DATE
from EDWFIN.PSP_LABOR_SCHD_DAY_F_ROLLUP A
left join ( SELECT
pay_range_start_date_key,aa_person_natural_key,aa_person_assignment_key,schedule_line_id,MAX(src_created_date) src_created_date,MAX(src_last_update_date) src_last_update_date
FROM
edwfin.psp_labor_schd_day_f_rollup_frs_356
GROUP BY
pay_range_start_date_key,schedule_line_id
) B
on A.PAY_RANGE_START_DATE_KEY = B.PAY_RANGE_START_DATE_KEY AND
A.AA_PERSON_NATURAL_KEY = B.AA_PERSON_NATURAL_KEY AND
A.AA_PERSON_ASSIGNMENT_KEY = B.AA_PERSON_ASSIGNMENT_KEY AND
A.SCHEDULE_LINE_ID = B.SCHEDULE_LINE_ID