2012-01-18 7 views
1

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

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

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

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

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

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

ответ

1

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

Как только оценки определены, вы можете отсортировать результаты на основе оценки и составить список тестов для каждого балла. Используя этот список, вы можете создать некоторый динамический 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

Интересная идея. Я попробую. Он должен хорошо работать для экзаменов, у которых есть несколько вопросов (менее 10). – David

0

вы можете создать запрос типа:

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 

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

Смежные вопросы