次の更新ステートメントを修正して、実行速度を上げるにはどうすればよいですか?
次のDMLがあります。
UPDATE rc_usutb011 u
SET cod_ant=(
SELECT cod_hst
FROM rc_pdptb101 p
WHERE ocip_hst=ocip_ant
AND p.sector=u.sector
);
説明計画は次のようになります。
SQL> select * from table(dbms_xplan.display());
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2656911336
------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
------------------------------------------------------------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 17M| 1042M| 71M (25)|238:59:58 | | | |
| 1 | UPDATE | RC_USUTB011 | | | | | | | |
| 2 | PX COORDINATOR | | | | | | | | |
| 3 | PX SEND QC (RANDOM) | :TQ10000 | 17M| 1042M| 7632 (3)| 00:01:32 | Q1,00 | P->S | QC (Rand) |
| 4 | PX BLOCK ITERATOR | | 17M| 1042M| 7632 (3)| 00:01:32 | Q1,00 | PCWC | |
| 5 | TABLE ACCESS FULL | RC_USUTB011 | 17M| 1042M| 7632 (3)| 00:01:32 | Q1,00 | PCWP | |
| 6 | TABLE ACCESS BY INDEX ROWID| RC_PDPTB101 | 1 | 61 | 3 (0)| 00:00:01 | | | |
|* 7 | INDEX UNIQUE SCAN | I_RC_PDPTB101_12 | 1 | | 2 (0)| 00:00:01 | | | |
------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
7 - access("OCIP_HST"=:B1 AND "P"."SECTOR"=:B2)
19 rows selected.
Elapsed: 00:00:00.11
SQL>
---------------------------------------------------
私の並列構成は次のとおりです
SQL> SELECT * FROM v$px_process_sysstat WHERE statistic LIKE 'Servers%';
STATISTIC VALUE
------------------------------ ----------
Servers In Use 8
Servers Available 0
Servers Started 8
Servers Shutdown 0
Servers Highwater 8
Servers Cleaned Up 0
6 rows selected.
Elapsed: 00:00:00.45
SQL> show parameter parallel
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
fast_start_parallel_rollback string LOW
parallel_adaptive_multi_user boolean TRUE
parallel_automatic_tuning boolean FALSE
parallel_execution_message_size integer 2152
parallel_instance_group string
parallel_max_servers integer 40
parallel_min_percent integer 0
parallel_min_servers integer 0
parallel_server boolean FALSE
parallel_server_instances integer 1
parallel_threads_per_cpu integer 2
recovery_parallelism integer 0
SQL>
バッファー:
SQL> SELECT * FROM V$PX_PROCESS_SYSSTAT WHERE STATISTIC LIKE 'Buffers%';
STATISTIC VALUE
------------------------------ ----------
Buffers Allocated 24
Buffers Freed 0
Buffers Current 24
Buffers HWM 24
Elapsed: 00:00:00.07
SQL>
cPU情報
SQL> show parameter cpu
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
cpu_count integer 4
parallel_threads_per_cpu integer 2
SQL>
助けてください。
ありがとう。
たくさんの行を更新しています。何があっても時間がかかります。
ただし、結合の更新を試みることもできます(ルックアップテーブルにINDEX UNIQUE SCAN
があるため)、インラインインデックスループよりも確実に機能します。
UPDATE (SELECT u.cod_ant, p.cod_hst
FROM rc_usutb011 u
JOIN rc_pdptb101 p
ON ocip_hst = ocip_ant
AND p.sector=u.sector)
SET cod_ant = cod_hst
WHERE cod_ant != cod_hst
これは、rc_usutb011
のすべてのレコードにrc_pdptb101
の既存の再コードがあることを前提としています。そうでない場合は、LEFT OUTER JOINを使用して同等のクエリを作成する必要があります。
問題はインデックスではありませんが、このステートメントはテーブルRC_USUTB011のすべての行を更新し、それは約1700万です。
いくつの行を更新する必要がありますか?
SELECT cod_hst FROM RC_PDPTB101 p WHERE ocip_hst=ocip_ant;
更新文を次のように書き直します。
UPDATE RC_USUTB011 u
SET cod_ant=(SELECT cod_hst FROM RC_PDPTB101 p WHERE ocip_hst=ocip_ant AND p.sector=u.sector)
WHERE EXISTS (SELECT 1 from RC_PDPTB101 p1 WHERE ocip_hst=ocip_ant AND p1.sector=u.sector);