PERSON_ID の主キーを持つテーブル DASHBOARD があります。
別のテーブル ALERT_EVENTS にクエリを実行する MERGE ステートメントを使用して、各列のすべての PERSON_ID を入力したいと考えています。
各列のMERGEステートメントを作成しました。以下はクエリの1つです-
MERGE INTO DASHBOARD D
USING
(SELECT PERSON_ID FROM PERSON) P
ON (D.PERSON_ID = P.PERSON_ID)
WHEN MATCHED THEN
UPDATE SET D.ZONES = (SELECT COUNT(EVENT_ID) FROM ALERT_EVENTS WHERE PERSON_ID = P.PERSON_ID AND EMAIL_ALERT_TYPE_ID = '40') WHERE D.PERSON_ID = P.PERSON_ID
WHEN NOT MATCHED THEN
INSERT (D.PERSON_ID)
VALUES (P.PERSON_ID);
私の問題は、このクエリの実行に時間がかかりすぎることです。通常は約 50 分です。
DASHBOARD テーブルには 4000 個の PERSON_ID があり、ALERT_EVENTS テーブルには 140 万個の EVENT_ID があります。ALERT_EVENTS テーブルは、次の列で構成されています -
"EVENT_ID" NUMBER(*,0) NOT NULL ENABLE,
"PERSON_ID" NUMBER(*,0) NOT NULL ENABLE,
"DEVICE_ID" NUMBER(*,0) NOT NULL ENABLE,
"ALERT_TYPE_ID" NUMBER(*,0) NOT NULL ENABLE,
"EVENT_DATE_TIME" DATE NOT NULL ENABLE,
"TEXT" VARCHAR2(4000 BYTE),
"STATUS" NUMBER(*,0) DEFAULT 0 NOT NULL ENABLE,
"PROC_STATUS_ID" NUMBER(*,0) DEFAULT 1 NOT NULL ENABLE,
"ALERT_STATUS_ID" NUMBER DEFAULT 1 NOT NULL ENABLE
and one UNIQUE index on EVENT_ID.
インデックスの追加と削除を試みましたが (1 つのインデックスと 3 つのインデックスで試しました)、パフォーマンスが向上しないようです。
EXPLAIN PLAN (下記) に基づいて、データベースは MERGE ステートメントを実行するときに常に FULL TABLE SCAN を実行する必要があるため、テーブル構造に問題があると思います。
Operation Name Rows Bytes Cost (%CPU) Time
MERGE STATEMENT 4127 314K 21 (5) 00:00:01
MERGE DASHBOARD
VIEW
HASH JOIN OUTER 4127 120K 21 (5) 00:00:01
INDEX FAST FULL SCAN PK_PERSON 4127 16508 4 (0) 00:00:01
TABLE ACCESS FULL DASHBOARD 4215 107K 16 (0) 00:00:01
SORT AGGREGATE 1 7
TABLE ACCESS FULL ALERT_EVENTS 27 189 5247 (2) 00:01:03
テーブルを分割するつもりでしたが、Oracle Standard しかなく、Enterprise がないため、含まれていません。
パーティションを使用せずにこのマージ ステートメントを高速化するにはどうすればよいですか?
ほとんどの行を破棄することを検討していますが、これはわずかに役立ちますが、根本的な問題はまだ存在しています。
ここで何が欠けていますか?
アイデアをお寄せいただきありがとうございます。