Очень долго работает Update запрос Oracle

Подскажите как можно ускорить апдейт. На данный момент работает 12+ часов. В таблице TABLE и TABLE_NEW примерно по 1 млн записей, что не так много.

Разработчик, который делал код ушел в закат, наверное торопился и сделал апдейт не оптимальным.

update TABLE ix 
    set (PLAN,Name)=(select distinct s.PLAN, s.name
                     from TABLE_NEW s
                     where ix.DBKEY=s.DBKEY and ix.STORE=s.STORE and ix.PLAN<>s.PLAN)
    where ix.DBKEY in(select ix.dbkey 
                     from TABLE ix, (select distinct DBKEY, STORE, PLAN, name from TABLE_NEW) s 
                     where ix.DBKEY=s.DBKEY and ix.STORE=s.STORE and ix.PLAN<>s.PLAN);

Ответы (1 шт):

Автор решения: Diyor Khakimov

Необходимо выполнить следующие изменения:

  1. Использовать оператор MERGE вместо использования подзапросов, он выполняется быстрее.

Обновленный запрос:

MERGE INTO TABLE ix
USING (
    SELECT DISTINCT DBKEY, STORE, PLAN, NAME
    FROM TABLE_NEW
) s
ON ix.DBKEY = s.DBKEY 
AND ix.STORE = s.STORE
AND ix.PLAN <> s.PLAN
WHEN MATCHED THEN
UPDATE SET ix.PLAN = s.PLAN, ix.NAME = s.NAME;
  1. Необходимо создать индексы - ускорит поиск совпадающих строк
CREATE INDEX IDX_TABLE_NEW ON TABLE_NEW (DBKEY, STORE, PLAN);
  1. Если данных очень много можно обновлять частями
UPDATE TABLE ix
SET (PLAN, NAME) = (
    SELECT s.PLAN, s.NAME
    FROM TABLE_NEW s
    WHERE ix.DBKEY = s.DBKEY
    AND ix.STORE = s.STORE
    AND ix.PLAN <> s.PLAN
)
WHERE EXISTS (
    SELECT 1 FROM TABLE_NEW s
    WHERE ix.DBKEY = s.DBKEY
    AND ix.STORE = s.STORE
    AND ix.PLAN <> s.PLAN
)
AND ROWNUM <= 10000; -- обновлять по 10 000 строк за раз

Также можно обновлять в многопотоке

ALTER TABLE TABLE_NEW PARALLEL 4;

P.S.: Советую сначала попробовать с MERGE и индексами, если не поможет то уже переходить на пункты 3 и 4 (с пунктом 4 лучше быть осторожней рекомендуемое-максимальное значение параллелизации 8 потоков)

→ Ссылка