0

我正在尝试为我正在处理的网站构建搜索查询,该查询构建最近/在线玩家的列表,他们正在玩或想要玩的游戏,他们正在玩的平台,如果他们有麦克风,他们在平台上的玩家标签/图像以及他们想要玩的游戏模式。以下查询为我做这件事。但是,它非常缓慢。我已经为存活 1 分钟的数据创建了一个缓存。

此外,users_games_modes ugm它加入了user_id而不是game_id像我想要的那样。我不知道如何在加入之前game_id不移动也使其匹配。games_modes如果我在连接之前移动连接,我将如何连接连接结果中的数据ugm?(我希望这是有道理的)

  • 通过使用ou1.game_id

我对 where 或 join on 语句中的每个项目都有索引。 是通过使用 PHP 和 MySQL的PDO 语言动态添加
ou1.stop

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

游戏模式索引:

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:添加了一个game_idusers_games_modes,将运行时间从 16 秒降低到 2.4 秒。
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_CONCATusers_games_modesgames_modes更改了更新工具中的代码以在更改users_games_modes时更新条目users_games_modes_temp

这将整个查询从 16 秒更改为 0.002 秒。

我认为运行时的巨大变化是由于连接users_games_modes为每行查询中的所有用户拉取所有游戏。

于 2013-01-04T21:48:48.927 回答