【发布时间】:2021-08-09 16:16:51
【问题描述】:
我正在尝试在 oracle 中使用合并语句进行更新,源有 20M 记录,目标有 118M 记录。合并的性能需要很长时间。下面列出的是我的合并声明。我还放了解释计划的截图供参考。
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,
aa_person_natural_key,
aa_person_assignment_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;
【问题讨论】:
-
您使用的是 MySQL 还是 Oracle?
-
@jarlh 我正在使用 oracle
-
这是一次性交易还是您经常需要执行的查询?由于它是单个查询,所有更新都作为一个事务执行,这会减慢整个过程。如果我必须这样做,我会使用一些代码来完成并提交每 1000 次左右的更新。
-
@Tarik 不,它只是一次更新
-
具有多个提交的循环迭代,尤其是使用外部脚本,将总是比单个 SQL 事务花费更长的时间,可能要长几个数量级.这将强制执行多个 CPU 上下文切换、网络 i/o(甚至在 localhost 上)、重做日志同步操作和控制文件更新,否则这些操作将不存在。如果您将其分解,您还将在事务中失去任何逻辑一致性(如果源数据在中间过程中发生更改会发生什么?)。我在您的解释计划中看不到任何明显的调整机会,除非您将
B设为物化视图。
标签: sql oracle oracle11g oracle10g sql-merge