2016-02-04 5 views
2

Я пытался найти его в Интернете, но не смог найти ничего, что уладит мои сомнения.MERGE vs. UPDATE

Я хочу выяснить, какой из них лучше использовать, когда и почему?

Я знаю, что 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 

В моем случае, я должен обновить таблицу с около 200mil записей в одном enviorment, на основании той же таблицы из другого enviorment, где изменение имеет происходить на поле SERIAL_NUMBER. Как вы можете видеть, он выбирает onces из этой огромной таблицы.

С другой стороны, я могу использовать UPDATE ЗАЯВЛЕНИЕ вроде этого:

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) 

Как вы можете видеть, это выбрать из огромного стола уже дважды. Итак, мой вопрос: что лучше? почему? .. в каких случаях один будет лучше, чем другой.

Заранее спасибо.

+0

Не можете ли вы исправить это обновление (перейдите к таблице соединений на себя), а затем проверьте скорость/план выполнения? – Veljko89

+0

@ Veljko89 и как я могу это сделать в оракуле? – sagi

+0

Не работает много с оракулом, но я уверен, что в нем есть внутреннее соединение ... Я мог бы попытаться записать его, дайте немного минут – 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. Так что U'd сказал, что обновление будет быстрее, чем слияние здесь? Зачем? – sagi

+0

@sagi, просто проверьте и сравните оба подхода с меньшим набором данных с теми же индексами ...;) – MaxU

+0

Вот что я собираюсь делать :) Я также хочу попробовать другой подход, будет цикл (для rec в (.... используя Oracle Rownum). Я просто спросил, есть ли какие-то правила об этом и времена, что будет быстрее слить/обновить .. в любом случае я отвечу на ваш ответ, но это все еще не отвечает на мой вопрос – sagi