Мне нужно оптимизировать запрос для ранжирования, которое занимает вечность (сам запрос работает, но я знаю, что он ужасен, и я только что попробовал его с большим количеством записей, и он дает время ожидания).
Я кратко объясню модель. У меня есть 3 стола: игрок, команда и player_team. У меня есть игроки, которые могут принадлежать команде. Очевидно, что игроки хранятся в таблице игроков, а команды в команде. В моем приложении каждый игрок может сменить команду в любое время, и необходимо вести журнал. Тем не менее, игрок считается принадлежащим только одной команде в данный момент. Текущая команда игрока - последняя, к которой он присоединился.
Структура игрока и команды не имеет отношения, я думаю. У меня есть идентификатор столбца PK в каждом. В player_team у меня есть:
id (PK)
player_id (FK -> player.id)
team_id (FK -> team.id)
Теперь каждой команде назначается очко для каждого присоединившегося игрока. Итак, теперь я хочу получить рейтинг первых N команд с наибольшим количеством игроков.
Моя первая идея состояла в том, чтобы сначала получить текущих игроков из player_team (то есть один рекорд для каждого игрока; эта запись должна быть текущей командой игрока). Мне не удалось найти простой способ сделать это (пробовал GROUP BY player_team.player_id HAVING player_team.id = MAX (player_team.id), но это не помогло.
Я пробовал несколько запросов, которые не работали, но сумели заставить это работать.
SELECT
COUNT(*) AS total,
pt.team_id,
p.facebook_uid AS owner_uid,
t.color
FROM
player_team pt
JOIN player p ON (p.id = pt.player_id)
JOIN team t ON (t.id = pt.team_id)
WHERE
pt.id IN (
SELECT max(J.id)
FROM player_team J
GROUP BY J.player_id
)
GROUP BY
pt.team_id
ORDER BY
total DESC
LIMIT 50
Как я уже сказал, это работает, но выглядит очень плохо и работает хуже, поэтому я уверен, что должен быть лучший путь. У кого-нибудь есть идеи по оптимизации этого?
Кстати, я использую mysql.
Заранее спасибо
Добавление объяснения. (Извините, не уверен, как правильно отформатировать его)
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t ALL PRIMARY NULL NULL NULL 5000 Using temporary; Using filesort
1 PRIMARY pt ref FKplayer_pt77082,FKplayer_pt265938,new_index FKplayer_pt77082 4 t.id 30 Using where
1 PRIMARY p eq_ref PRIMARY PRIMARY 4 pt.player_id 1
2 DEPENDENT SUBQUERY J index NULL new_index 8 NULL 150000 Using index