【发布时间】:2013-01-05 05:48:48
【问题描述】:
我正在尝试为我正在开发的网站构建搜索查询,以构建最近/在线玩家列表、他们正在玩或想玩的游戏、他们正在玩的平台,如果他们有麦克风、平台的玩家标签/图像以及他们想要玩的游戏模式。以下查询为我做这件事。但是,它非常缓慢。我已经为存活 1 分钟的数据做了一个缓存。
此外, users_games_modes ugm 加入了user_id,而不是game_id,就像我希望的那样。我不知道如何在加入之前不移动games_modes 的情况下使其与game_id 匹配。如果我先移动连接,我将如何连接来自ugm 连接的结果的数据? (我希望这是有道理的)
- 使用
ou1.game_id修复了这个问题
我对 where 或 join on 语句中的每个项目都有索引。ou1.stop 是通过 PDO 动态添加的
使用的语言 PHP 和 MySQL
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 输出:
games_modes 索引:
在线用户指数:
users_games_modes 索引:
- 编辑 1:删除了 2 个 JOIN,添加了一个 CASE 和一个子选择,从运行时中删除了一些内容,并使其更好地用于未来的更新。
- 绝大多数运行时间似乎来自
users_games_modes连接。当我删除它时,它从 16 秒变为 0.32 秒。我在user_id上有一个索引。 (我附上了users_games_modes的索引截图
- 绝大多数运行时间似乎来自
- 编辑 2:向
users_games_modes添加了一个game_id列,将运行时间从 16 秒降低到 2.4 秒。 - 更新了
users_games_modes4的索引截图
- 更新了
【问题讨论】:
-
我认为您应该看看如何提高查询的性能。向我们展示一些索引。
-
我添加了 EXPLAIN 和 2 个索引
标签: mysql