Производительность проблема с моим запросом. Пожалуйста, предложите - PullRequest
0 голосов
/ 28 сентября 2011
MERGE INTO Analysis a
USING ( SELECT * FROM  Data ) b
ON ( a.User_Id = b.User_Id AND a.Upgrade_Flag = 0 )
WHEN MATCHED THEN
UPDATE SET Status = NVL(a.Status, 'ACTIVATE');

Приведенный выше запрос работает нормально. Но когда присутствуют миллионы записей, это может привести к проблемам с производительностью. Есть ли альтернатива для вышеупомянутого запроса, чтобы получить лучшую производительность. Пожалуйста, предложите мне это. Спасибо за ваше время

Ответы [ 3 ]

1 голос
/ 28 сентября 2011

Не видя планов выполнения, я не могу предсказать, будет ли альтернатива более эффективной.Но я отмечаю, что вы не используете источник слияния в обновлении, что указывает на то, что это можно переписать как простой оператор обновления:

UPDATE Analysis a
SET Status = NVL(a.Status, 'ACTIVATE')
WHERE a.Upgrade_Flag = 0
AND a.User_Id IN (
  SELECT b.User_Id FROM Data b
)

Как всегда в случае с этими вещами, у вас есть выбор междуиспользуя предложение IN, как я показал, или предложение EXISTS с коррелированным подзапросом.Обычно стоит попробовать оба варианта при попытке настроить производительность, хотя, по крайней мере, в некоторых случаях оптимизатор попытается выполнить это преобразование самостоятельно.

0 голосов
/ 28 сентября 2011

Не совсем понятно, почему вы используете MERGE вместо простого ОБНОВЛЕНИЯ.

update analysis a
set a.status = 'ACTIVATE'
where a.status is null
and a.upgrade_flag = 0 
and a.user_id in ( select b.user_id from  data b )
/

Выбор только USER_ID из DATA вместо всей записи может ускорить процесс, предполагая, что DATA.USER_ID проиндексирован.

0 голосов
/ 28 сентября 2011

Запрос выглядит хорошо для меня. Может быть, вам стоит создать несколько индексов?

Создание индекса для Analysis.User_Id и индекса для Data.User_Id, если он еще не создан (первичный ключ создает индекс автоматически).

Или может также создать индекс для Analysis, содержащий оба столбца User_Id и Upgrade_Flag.

...