2013-02-16 3 views
2

Я пишу онлайн-программу тестирования математики и в настоящее время работаю над скриптами, чтобы вычислить ранг, который получил каждый пользователь. Следующий код работает, но я сжимаю каждый раз, когда вижу его.строка обновления на основе порядка в итоговой таблице

get_set() помещает результат запроса в $ пользователи

function rank_users_in_test($tid){ 
    $GLOBALS['DB']->get_set($users,"select user,test from user_results where test=$tid order by points desc,time"); 
    // $users are already in order by rank thanks to ORDER BY 
    $rank = 1; 
    foreach ($users as $u){ 
    $GLOBALS['DB']->query("update user_results set world_rank=$rank where user={$u['user']} and test={$u['test']}"); 
    $rank++; 
    } 
} 

Запрос в цикле заставляет меня плакать немного. Мой вопрос: существует ли способ, которым MySQL может автоматически обновлять рейтинг каждого пользователя в зависимости от того, каким образом они были получены в результате первого запроса? Существует связанный с этим вопрос here, но он не использует UPDATE.

Я использую MySQL 5.

+1

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

+0

Я знаю, но сайт выдерживает очень тяжелое движение в ночное время, когда результаты отпущены. У нас было такое, что результаты были только запрошены, но наши серверы замерли - слишком много соединений. Когда результаты статичны, наши серверы могут обрабатывать нагрузку. Проблема состоит в том, что конкурс становится все больше, и этот код достигает максимального времени выполнения 5min, которое позволяют наши серверы (я не могу это изменить). – twentylemon

+0

Создайте временную таблицу с полем «auto_increment» и «insert into mytemp (userid, points ...) выберите userid, точки из тестов ... упорядочивайте по точкам desc ...', чтобы иметь в одном запросе все Создано рангов –

ответ

0

Благодаря ring0 выше, следующему уменьшил время работы от нескольких минут до считанных секунд: D

create table temp (
    rank int auto_increment, 
    user int, 
    test int, 
    primary key(rank) 
); 

insert into temp(user,test) (select user,test from user_results where test=$tid order by points desc,time); 

update user_results ur, temp t set ur.world_rank=t.rank where ur.user=t.user and ur.test=t.test; 

drop table temp; 
Смежные вопросы