Оптимизация большого количества запросов на обновление - PullRequest
1 голос
/ 18 января 2012

У меня есть приложение, в котором пользователи начинают проходить тесты, а иногда они забывают закончить / отправить свои тесты. Администраторы запросили кнопку, по которой они могли бы нажать, которая проходит через систему, находит все неподтвержденные экзамены и оценивает их.

Этот процесс выполняется одним оператором выбора для загрузки всех экзаменов, на которые влияют. Затем процесс в памяти определяет оценку каждого пользователя. Проблема в том, что обновление базы данных с оценкой каждого пользователя происходит очень медленно. Запросы на обновление занимают несколько минут, и выполняются сотни или тысячи операторов обновления (в зависимости от того, сколько неподтвержденных экзаменов ожидает обработки). Мой сервер базы данных использует MySQL.

Есть ли хороший способ объединить эти запросы на обновление в одно обновление? Каждый пользователь получает уникальный балл за экзамен. Я нашел несколько ссылок о том, как это сделать, но мои коллеги-разработчики говорят мне, что они не поддерживаются и слишком сложны. Большинство из них имеют дело с добавлением инструкций к запросу на обновление (по одному на каждый набранный экзамен). Вот пример одного предложения:

http://dashasalo.com/2009/06/18/update-multiple-rows-with-different-values/

Есть ли какая-то другая идея, которую я упускаю, которая может улучшить производительность этого процесса? Спасибо!

Примечание. У меня правильно настроены индексы для этой таблицы, и каждый отдельный запрос занимает от 0,2 до 0,5 секунды. Я также предложил работу cron в ночное время или автоматическую очистку. Администраторы отклонили это, заявив, что хотят контролировать, когда происходит процесс очистки, и что cron / автоматический / ночной процесс для них неприемлем.

Ответы [ 2 ]

1 голос
/ 18 января 2012

Когда вы говорите, что оценка выполняется в памяти, я предполагаю, что вы имеете в виду, что приложение выбирает тестовые ответы из базы данных и оценивает их.

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

UPDATE tests
SET score = 100
WHERE TestID IN (1,2,10,1000);

UPDATE tests
SET score = 99
WHERE TestID IN (8,12,46,2000);
....
0 голосов
/ 18 января 2012

Вы можете сгенерировать запрос, например:

UPDATE targettable tt
JOIN (SELECT 1 as user_id, 100 as score
  UNION ALL
  SELECT 2 as user_id, 150 as score) st
USING (user_id)
SET tt.score = st.score

Где подвыбор может быть UNION из нескольких сотен строк.В качестве альтернативы вы можете создать временную таблицу, заполнить ее подмножеством данных, сделать аналогичное JOIN, усечь, зафиксировать и с самого начала.

...