我正在尝试为我正在制作的网站构建搜索查询,以构建最近/在线玩家列表,他们正在玩或想玩的游戏,他们正在玩哪个平台,如果他们有一个麦克风,他们的平台游戏者标签/图像以及他们想要玩的游戏模式。以下查询为我做了这个。但是,它很慢。我为存活1分钟的数据做了一个缓存。
此外, users_games_modes ugm
加入了user_id
而非game_id
,就像我希望的那样。我不知道如何在game_id
之前将其与games_modes
匹配,而无需在加入前移动ugm
。如果我之前移动联接,我将如何加入ou1.game_id
联接的结果数据? (我希望这是有道理的)
ou1.stop
我在where或join语句中的每个项目上都有索引
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;
是通过PDO动态添加的
语言使用PHP和MySQL
users_games_modes
这是sql-adminer的EXPLAIN输出:
games_modes index:
在线用户指数:
users_games_modes index:
user_id
加入。当我删除它,它从16秒到0.32秒。我有users_games_modes
的索引。 (我附上了game_id
users_games_modes
添加了users_games_modes
列,将运行时间从16秒降低到2.4秒。答案 0 :(得分: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;
我删除了users_games_modes
和games_modes
上的LEFT JOIN和GROUP_CONCAT,并更改了更新users_games_modes
的工具中的代码,以便在更改users_games_modes_temp
时更新条目。
这将整体查询从16秒更改为0.002秒。
我认为运行时的巨大变化是由于连接为每一行的查询中的所有用户提取users_games_modes
所有游戏。