簡體   English   中英

如何更改我的表以使Oracle合並運行得更快?

[英]How can I alter my table to make Oracle merge run faster?

我有一個表,DASHBOARD,主鍵是PERSON_ID。
我想使用MERGE語句為每列填充所有PERSON_ID,該語句向另一個表查詢計數ALERT_EVENTS。

我為每一列編寫了MERGE語句,下面是其中一個查詢 -

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,因此它不是一個包含的功能。

如何在不使用分區的情況下加速此合並語句?

我正在考慮拋棄大部分行,這會有所幫助,但潛在的問題仍然存在。

我在這里錯過了什么?

提前感謝任何想法。

我沒有在Oracle上使用merge,所以不是100%確定這會有效,但以下應該更快,特別是在alert_events (email_alert_type_id, person_id)alert_events (person_id, email_alert_type_id)上有索引。 理想情況下,您將使用第一個並在查詢計划中查看合並連接,但我不確定Oracle的查詢優化器是否可以執行此操作。

merge into 
    dashboard d
using (
    select
        p.person_id,
        count(e.person_id) zones
    from
        person p
            left outer join
        alert_events e
            on p.person_id = e.person_id and 
               e.email_alert_type_id = '40' 
    group by
        p.person_id
    ) x
on
    (d.person_id = x.person_id)
when matched then update
    set d.zones = x.zones
when not matched then insert (person_id, zones)
    values (x.person_id, x.zones);

我還在插入中包含了區域,刪除它以保持與原始查詢一致是微不足道的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM