0

最近/オンラインのプレーヤー、彼らがプレイしている、またはプレイしたいゲーム、彼らがプレイしているプラ​​ットフォーム(ある場合)のリストを作成する、私が取り組んでいるサイトの検索クエリを作成しようとしています。マイク、プラットフォーム用のゲーマータグ/画像、およびプレイしたいゲームモード。次のクエリは私のためにそれを行います。ただし、非常に遅いです。1分間存続するデータのキャッシュを作成しました。

さらに、users_games_modes ugmはに結合されており、私が望んでいるようなものではuser_idありません。参加する前に移動せずgame_idに、どうやってそれを一致させることができるのかわかりません。結合の前に結合を移動した場合、結合の結果のデータをどのように結合しますか?(私はそれが理にかなっていることを願っています)game_idgames_modesugm

  • を使用してこれを修正しましたou1.game_id

whereまたはjoinonステートメントの各項目にインデックスがあります。
は、 PHPおよびMySQLを使用ou1.stopするPDO言語を介して動的に追加されます

SELECT
    ou1.id as oid,
    ou1.user_id,
    ou1.game_id as game_id,
    CONCAT(SUBSTRING(ou1.comment, 1, 7), '...') as comment,
    users_systems.mic,
    users_gamernames.user_name,
    games.game_name,
    ou1.start,
    ou1.stop,
    ou1.system_id as system_id,
    (select value from users_settings where users_settings.user_id = ou1.user_id and users_settings.setting = 'display_name') as display_name,
    CASE
        WHEN ou1.system_id = '1' THEN 'xbox_tile'
        WHEN ou1.system_id = '2' THEN 'ps3_tile'
        WHEN ou1.system_id = '3' THEN 'steam_tile'
    END AS platform,
    (select value from users_settings where users_settings.user_id = ou1.user_id and users_settings.setting = platform) as platform_tile,
    GROUP_CONCAT(DISTINCT gm.short_name ORDER BY gm.short_name SEPARATOR ', ') as modes
FROM online_users as ou1
LEFT JOIN online_users ou2 ON (ou1.user_id = ou2.user_id and ou1.id < ou2.id and ou1.stop < '2013-01-28 23:59:59')
LEFT JOIN users_gamernames ON (users_gamernames.user_id = ou1.user_id AND users_gamernames.system_id = ou1.system_id)
LEFT JOIN users_systems ON (ou1.user_id = users_systems.user_id AND ou1.system_id = users_systems.system_id)
LEFT JOIN users_games_modes ugm ON (ou1.user_id = ugm.user_id AND ugm.game_id = ou1.game_id)
LEFT JOIN games_modes gm ON (ugm.mode_id = gm.id AND ou1.game_id = ou1.game_id)
RIGHT JOIN games ON (ou1.game_id = games.id)
WHERE ou2.id IS NULL
AND ou1.id IS NOT NULL
AND ou1.stop<='2013-01-28 23:59:59'
GROUP BY ou1.system_id, ou1.user_id
ORDER BY ou1.stop ASC
LIMIT 50;

sql-adminerからのEXPLAIN出力は次のとおりです。

http://i.imgur.com/N1ykp.png

http://i.imgur.com/N1ykp.png

games_modesインデックス:

http://i.imgur.com/m9DLF.png

http://i.imgur.com/m9DLF.png

オンラインユーザーインデックス:

http://i.imgur.com/jf0wz.png

http://i.imgur.com/jf0wz.png

users_games_modesインデックス:

http://i.imgur.com/I0PUR.png

http://i.imgur.com/I0PUR.png

  • 編集1:2つのJOINを削除し、CASEを追加し、サブセレクトを追加しました。これにより、ランタイムが少し削除され、将来の更新のために少し改善されました。
    • 実行時間の大部分はusers_games_modes参加によるもののようです。取り外すと16秒から0.32秒になります。にインデックスがありuser_idます。(インデックスのスクリーンショットを添付しましたusers_games_modes
  • 編集2:実行時間を16秒から2.4秒に短縮するgame_id列を追加しました。users_games_modes
    • 4のインデックススクリーンショットを更新しましたusers_games_modes
4

1 に答える 1

0
        SELECT 
            ou1.id as oid,
            ou1.user_id,
            ou1.comment,
            users_systems.mic,
            users_gamernames.user_name,
            games.game_name,
            ou1.start,
            ou1.stop,
            ou1.system_id as system_id,
                (select value from users_settings where users_settings.user_id = ou1.user_id and users_settings.setting = 'display_name') as display_name,
                CASE
                    WHEN ou1.system_id = '1' THEN 'xbox_tile'
                    WHEN ou1.system_id = '2' THEN 'ps3_tile'
                    WHEN ou1.system_id = '3' THEN 'steam_tile'
                END AS platform,
                (select value from users_settings where users_settings.user_id = ou1.user_id and users_settings.setting = platform) as platform_tile,
                ugmt.modes
        FROM online_users as ou1
        LEFT JOIN users_gamernames ON (users_gamernames.user_id = ou1.user_id AND users_gamernames.system_id = ou1.system_id)
        LEFT JOIN users_systems ON (ou1.user_id = users_systems.user_id AND ou1.system_id = users_systems.system_id)
        LEFT JOIN users_games_modes_temp ugmt ON (ou1.user_id = ugmt.user_id AND ugmt.game_id = ou1.game_id)
        RIGHT JOIN games ON (ou1.game_id = games.id)
        WHERE ou1.expired=0
        AND ou1.start<='2013-01-04 21:47'
        AND ou1.stop>='2013-01-04 21:47'
        GROUP BY ou1.id
        ORDER BY ou1.stop DESC
        LIMIT 50;

LEFT JOINとGROUP_CONCATを削除しusers_games_modes、変更時にエントリを更新するように更新するgames_modesツールのコードを変更しました。users_games_modesusers_games_modes_temp

これにより、クエリ全体が16秒から0.002秒に変更されました。

ランタイムの大きな変化は、users_games_modes各行のクエリですべてのユーザーのすべてのゲームのをプルする結合によるものだと思います。

于 2013-01-04T21:48:48.927 に答える