【发布时间】:2017-11-29 15:23:18
【问题描述】:
当同一脚本中以前的类似更新在大约一个小时内完成时,我有一条 Oracle Update 语句挂起。
我有两张桌子:
表 A:ID、Masked_Account、Original_Account(9+ 百万行,一个交叉引用表)。
表 B:UID、Prefix_Pan、Pan、Masked(1.3+ 十亿行)。
我正在尝试在 Table B Pan 列与 Table A Original_Account 列匹配的每个实例中使用 Table A Masked_Account 列更新 Table B Pan 列。
我正在分批更新每批 1 亿条记录,并随后提交。
例如,下面列出的更新 SQL 脚本在大约一个小时内完成:
UPDATE [TABLE B] optim
SET optim.PAN = (SELECT MASKED_ACCOUNT FROM [TABLE A] pans
WHERE optim.PAN = pans.ORIG_ACCOUNT), optim.MASKED = '1'
WHERE optim.OPTIM_UID BETWEEN 1200000000 AND 1300000000
AND EXISTS (SELECT 1
FROM [TABLE A] pans
WHERE optim.PAN = pans.ORIG_ACCOUNT);
我的最后一个更新 SQL 语句挂起并且永远不会完成:
UPDATE [TABLE B] optim
SET optim.PAN = (SELECT MASKED_ACCOUNT FROM [TABLE A] pans
WHERE optim.PAN = pans.ORIG_ACCOUNT), optim.MASKED = '1'
WHERE optim.OPTIM_UID > 1300000000
AND EXISTS (SELECT 1
FROM [TABLE A] pans
WHERE optim.PAN = pans.ORIG_ACCOUNT);
解释计划 (dbms_xplan.display) 结果:
Plan hash value: 4037184420
----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 250 | 9250 | 465K (1)| 00:00:10 |
| 1 | UPDATE | OPTIM_SMRY_FTR_CHKMC_EXTRACT | | | | |
|* 2 | HASH JOIN RIGHT SEMI | | 250 | 9250 | 239K (1)| 00:00:05 |
| 3 | INDEX STORAGE FAST FULL SCAN | IDX_PANS_ORIG_ACCT | 82 | 902 | 10123 (1)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID BATCHED| OPTIM_SMRY_FTR_CHKMC_EXTRACT | 32M| 796M| 228K (1)| 00:00:05 |
|* 5 | INDEX RANGE SCAN | PK_OP_47 | 22M| | 53465 (1)| 00:00:02 |
| 6 | TABLE ACCESS BY INDEX ROWID BATCHED | PANS | 1 | 22 | 604 (1)| 00:00:01 |
|* 7 | INDEX RANGE SCAN | IDX_PANS_ORIG_ACCT | 1 | | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OPTIM"."PAN"="PANS"."ORIG_ACCOUNT")
5 - access("OPTIM"."OPTIM_UID">1300000000)
7 - access("PANS"."ORIG_ACCOUNT"=:B1)
Note
-----
- dynamic statistics used: dynamic sampling (level=AUTO)
谁能告诉我在最后一个更新 SQL (optim.OPTIM_UID > 1300000000) 上我需要做些什么不同的事情,这样它就不会挂起,或者我应该如何以不同的方式处理整个更新过程?
【问题讨论】:
-
很多问题。在 1200000000 和 1300000000 之间真的有 100 毫米的行吗?我的猜测是没有。您可能有更多行大于 1300000000。您检查过阻塞锁吗?它似乎在移动吗? (使用撤消/回滚)您的 dbas 怎么说?
-
在 1200000000 和 1300000000 之间确实有 1 亿行。Optim_UID 确实是“rownum”。表 B 的总行数为 1,322,566,115。上次我尝试运行最后一批更新(> 1300000000)时,我没有看到任何阻塞锁,但已经运行了 22 多个小时。由于其他更高的优先级,目前无法让数据库管理员查看它。
-
13 亿次更新,每一次更新都需要对 masked_account 的子查询。而且我相信 EXISTS 部分也会为每一行触发。加入两个表并插入工作表可能会更快吗?然后删除并重命名? optim.PAN 上是否有可以先禁用的索引?
-
能否请您在更新中运行解释计划并使用结果编辑问题。
-
如果在慢查询或挂起查询运行时查看 V$SESSION 中的 EVENT,您可以查看它是否正在等待锁定。锁是一种排队等待事件。您还可以在各种 GUI 工具中看到这一点。
标签: oracle