【发布时间】:2015-01-11 19:51:28
【问题描述】:
我有一个包含 900 万条记录的表。要求如下: 1. 插入900万条记录的表。每个条目都有一个 rowid,它使用触发器插入到表中。 2. 我们有两列必须在名为 First_Instance 和 First_Instance_Date 的同一个表中单独更新。 3. 这些 First Instance 列应包含表中存在的重复记录的第一个 Rowid 编号。
我们正在使用下面的代码来更新
UPDATE TABLE_A T4
SET (T4.ROW_ID_FIRST_INS, T4.ROW_ID_DT_FIRST_INS) =
( SELECT MIN (T3.ROW_ID), MIN (T3.UPDATE_DATE)
FROM TABLE_A T3
WHERE T3.SOURCE(+) = T4.SOURCE
AND SUBSTR (T3.TABLE_NAME,
1,
REGEXP_INSTR (T3.TABLE_NAME,
'\_[0-9]{8}T',
1,
1,
0))
|| SUBSTR (T3.TABLE_NAME,
REGEXP_INSTR (T3.TABLE_NAME,
'\_[0-9]{8}T',
1,
1,
1),
LENGTH (T3.TABLE_NAME)
- REGEXP_INSTR (T3.TABLE_NAME,
'\_[0-9]{8}T',
1,
1,
1)) =
SUBSTR (T4.TABLE_NAME,
1,
REGEXP_INSTR (T4.TABLE_NAME,
'\_[0-9]{8}T',
1,
1,
0))
|| SUBSTR (T4.TABLE_NAME,
REGEXP_INSTR (T4.TABLE_NAME,
'\_[0-9]{8}T',
1,
1,
1),
LENGTH (T4.TABLE_NAME)
- REGEXP_INSTR (T4.TABLE_NAME,
'\_[0-9]{8}T',
1,
1,
1))
AND NVL (T4.I_NAM, 'xx') =
NVL (T3.I_NAM, 'xx')
AND NVL (T4.J_NAM, 'xx') = NVL (T3.J_NAM, 'xx')
AND NVL (T4.SYS_NAM, 'xx') =
NVL (T3.SYS_NAM, 'xx')
AND NVL (T4.TG_TAB_NAM, 'xx') =
NVL (T3.TG_TAB_NAM, 'xx')
AND NVL (T4.PK, 'xx') = NVL (T3.PK, 'xx')
AND NVL (T4.ERR, 'xx') =
NVL (T3.ERR, 'xx')
AND NVL (T4.VAL, 'xx') =
NVL (T3.VAL, 'xx')
AND NVL (T4.ID, 'xx') = NVL (T3.ID, 'xx')
GROUP BY T4.FIELD,
T4.ERR,
T4.VAL,
T4.ID,
T4.PK,
T4.I_NAM,
T4.SYS_NAM,
T4.J_NAM)
WHERE T4.CURRENT_LOAD_ID = some number FROM CURSOR;
查询 3050 条记录需要 35 秒,但运行 4L 记录时。从过去 2 天开始,它没有停止运行。
Row_ID 是 PK 并且在所有分组列上创建了 NU 索引,除了少数大小为 4000 的列。
谢谢。
【问题讨论】:
-
你检查过桌子上的其他锁吗?
-
是的。没有锁。我为此制定了解释计划,但成本非常高……超过一百万。
-
如果我是你,我会跟踪会话,看看会发生什么。
-
顺便说一句,如果建议只使用 ROWID 作为主键,因为在执行此类语句时 ROWID 可能会发生变化:alter table t shrink space compact, alter table t move, flashback table t to ...
-
其实不是ROWID,而是由触发器插入的序列。看起来与罗伊德相似。我们必须对记录进行分组并为每个组更新它的第一个值。不过,我们有一个 DBA 团队在监控这项工作。
标签: sql oracle performance sql-update self-join