永遠にかかるランキングのためにクエリを最適化する必要があります(クエリ自体は機能しますが、それがひどいことはわかっています。かなりの数のレコードで試してみたところ、タイムアウトが発生しました)。
モデルについて簡単に説明します。player、team、player_team の 3 つのテーブルがあります。チームに所属できる選手がいます。当然のことながら、プレーヤーはプレーヤー テーブルに格納され、チームはチームに格納されます。私のアプリでは、各プレイヤーはいつでもチームを切り替えることができ、ログを維持する必要があります。ただし、プレイヤーは一度に 1 つのチームにのみ所属すると見なされます。プレーヤーの現在のチームは、最後に参加したチームです。
選手とチームの構造は関係ないと思います。それぞれに id 列 PK があります。player_team には次のものがあります。
id (PK)
player_id (FK -> player.id)
team_id (FK -> team.id)
現在、各チームには、参加した各プレイヤーのポイントが割り当てられています。そこで、今、プレイヤー数が最も多い最初の N チームのランキングを取得したいと考えています。
私の最初のアイデアは、最初に player_team から現在のプレーヤーを取得することでした (つまり、各プレーヤーの 1 つのレコード トップです。このレコードはプレーヤーの現在のチームでなければなりません)。簡単な方法を見つけることができませんでした (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