2016-02-04 38 views
2

我試圖在網上尋找它,但找不到任何解決我疑惑的事情。MERGE與更新

我想知道哪一個更好用,何時和爲什麼?

我知道MERGE通常用於upsert,但有一些情況下,使用子查詢進行正常更新必須從表中選擇兩次(從where子句中選擇一次)。

例如爲:

MERGE INTO TableA s 
USING (SELECT sd.dwh_key,sd.serial_number from [email protected]_devstg sd 
     where sd.dwh_key = s.dwh_key and sd.serial_number <> s.serial_number) t 
ON(s.dwh_key = t.dwh_key) 
WHEN MATCHED UPDATE SET s.serial_number = t.serial_number 

就我而言,我有一個enviorment更新與約200mil記錄的表的基礎上,從另一個enviorment,變革已經發生在SERIAL_NUMBER場相同的表。正如你所看到的,它從這張巨大的表格中選擇了一些。現在的兩倍

UPDATE TableA s 
SET s.serial_number = (SELECT t.serial_number 
         FROM [email protected]_Other t 
         WHERE t.dwh_serial_key = s.dwh_serial_key) 
WHERE EXISTS (SELECT 1 
       FROM [email protected]_Other t 
       WHERE t.dwh_serial_key = s.dwh_serial_key 
       AND t.serial_number <> s.serial_number) 

正如你所看到的,這個選擇從巨大的表:

在另一方面,我可以使用UPDATE語句這樣。所以,我的問題是,什麼更好?爲什麼?..哪一種情況會比另一種好..

在此先感謝。

+0

難道你不能修復該更新(去與自己的連接表),然後檢查速度/執行計劃? – Veljko89

+0

@ Veljko89和我會怎麼做在oracle? – sagi

+0

與oracle沒有多大作用,但我確定有內部聯接...我可以嘗試寫下來,給我幾分鐘 – Veljko89

回答

1

我會首先嚐試從遠程數據庫加載所有必要的數據到臨時表,然後使用該臨時表。

create global temporary table tmp_stage (
    dwh_key   <[email protected]_devstg>, 
    serial_number <[email protected]@to_devstg> 
) on commit preserve rows; 

insert into tmp_stage 
select dwh_key, serial_number 
from [email protected]_devstg sd 
where sd.dwh_key = s.dwh_key; 


/* index (PK on dwh_key) your temporary table if necessary ...*/ 

update (select 
     src.dwh_key src_key, 
     tgt.dwh_key tgt_key, 
     src.serial_number src_serial_number, 
     tgt.serial_number tgt_serial_number 
     from tmp_stage src 
     join TableA tgt 
     on src.dwh_key = tgt.dwh_key 
     ) 
    set src_serial_number = tgt_serial_number; 
+0

謝謝,我已經想過使用一個臨時表來存儲這兩個表之間的所有差異..我張貼我的問題來找出哪一個更好,MERGE或UPDATE。那麼你認爲在這裏合併更新會更快嗎?爲什麼? – sagi

+0

@sagi,只是測試和比較兩個方法在一個較小的數據集與相同的索引...;) – MaxU

+0

這就是我要做的:)我也想嘗試另一種方法將一個循環(對於rec中(....使用Oracle的Rownum)我只是問是否有一些關於它的規則和時間,它會更快地合併/更新..無論如何,我會upvote你的答案,但仍然不能回答我的問題 – sagi