web-dev-qa-db-ja.com

次の更新ステートメントを修正して、実行速度を上げるにはどうすればよいですか?

次の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>

助けてください。

ありがとう。

4
Marc Riera

たくさんの行を更新しています。何があっても時間がかかります。

ただし、結合の更新を試みることもできます(ルックアップテーブルに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を使用して同等のクエリを作成する必要があります。

1
Vincent Malgrat

問題はインデックスではありませんが、このステートメントはテーブル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);
0