Как оптимизировать этот пользовательский рейтинг - PullRequest
0 голосов
/ 23 декабря 2010

У меня есть 2 базы данных (пользователи, userRankings) для системы, которой необходимо обновлять рейтинг каждые 10 минут. Я использую следующий код для обновления этих ранжирований, который работает довольно хорошо, но все еще требуется полное сканирование таблицы, которое замедляет работу с несколькими сотнями тысяч пользователей.

mysql_query("TRUNCATE TABLE userRankings");
mysql_query("INSERT INTO userRankings (userid) SELECT id FROM users ORDER BY score DESC");
mysql_query("UPDATE users a, userRankings b SET a.rank = b.rank WHERE a.id = b.userid");

В таблице userRankings rank - это первичный ключ, а идентификатор пользователя - это индекс. Обе таблицы являются MyISAM (я подумал, может быть полезно сделать userRankings InnoDB).

Ответы [ 2 ]

0 голосов
/ 23 декабря 2010

Какой запрос на самом деле занимает большую часть времени? Держу пари, это третий.

Оцените ваш запрос, преобразовав его в SELECT:

SELECT a.rank, b.rank 
FROM users a, userRankings b
WHERE a.id = b.userid

Объясните может помочь вам отладить, как используются индексы.

Первое, что вы должны сделать, это отбросить тот старый синтаксис table1, table2. Это трудно читать и может быть очень неэффективно. Вы всегда должны использовать JOIN.

UPDATE users AS a
JOIN userRankings AS b ON a.id = b.userid
SET a.rank = b.rank

Это может решить вашу проблему прямо здесь - надеюсь, EXPLAIN поможет вам сузить круг вопросов. Убедитесь, что оба столбца (users.id и userRankings.userid) имеют одинаковый тип (например, один из них не подписан, а другой -, например).

Для получения дополнительной справки вам потребуется опубликовать больше данных (результаты SHOW CREATE TABLE для каждой таблицы, сколько времени занимает каждый запрос при их запуске, количество строк в таблицах).

0 голосов
/ 23 декабря 2010

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

select @rownum:=@rownum+1 ‘rank’, a.id 
from player a, (SELECT @rownum:=0) r 
order by score desc 
...