Очень долго работает 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
→ Ссылка
Необходимо выполнить следующие изменения:
- Использовать оператор 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;
- Необходимо создать индексы - ускорит поиск совпадающих строк
CREATE INDEX IDX_TABLE_NEW ON TABLE_NEW (DBKEY, STORE, PLAN);
- Если данных очень много можно обновлять частями
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 потоков)