我需要跟踪在我网站上在线的用户,这样我就可以在在线用户的头像旁边显示“在线”图标。
检测到这一点的第一步是跟踪用户上次看到的时间,这样每次用户请求页面时我都会进行UPDATE查询:
UPDATE `users`
SET `last_seen` = CURRENT_TIMESTAMP
WHERE `user_id` = '$user_id'
现在,在此之后,我执行另一个查询,这个查询以某个标准获取我网站的所有用户,以便我可以在主页上显示它们:
SELECT *,
(ACOS(SIN(0.7103989219783) * SIN(RADIANS(users.latitude)) + COS(0.7103989219783) * COS(RADIANS(users.latitude)) * COS(RADIANS(users.longitude) - -1.2894447135174)) * 6371) AS SearchRadius
FROM `users`
INNER JOIN `profiles` ON (
users.user_id = profiles.user_id
)
WHERE (users.latitude > 38.904216788163 AND users.latitude < 42.501503211837)
AND (users.longitude > -76.252301637251 AND users.longitude < -71.507178362749)
AND (ACOS(SIN(0.7103989219783) * SIN(RADIANS(users.latitude)) + COS(0.7103989219783) * COS(RADIANS(users.latitude)) * COS(RADIANS(users.longitude) - -1.2894447135174)) * 6371) < 200 AND users.sex = '1' AND users.seeking = '2' AND users.user_id != '1' AND users.account_status = '1' LIMIT 0, 10
不要介意这个查询的疯狂,基本上我要从我之前更新的users
表中选择。
当我一个接一个地执行这两个查询时,这些是我得到的时间:
1st query: 0.0392 seconds
2nd query: 1.5396 seconds
这会导致页面加载时间明显延迟。
现在,当我为在线用户创建一个单独的表并将第一个查询更改为:
UPDATE `online_users`
SET `last_seen` = CURRENT_TIMESTAMP
WHERE `user_id` = '$user_id'
时代变为:
1st query: 0.0411 seconds
2nd query: 0.0008 seconds
并且页面加载速度更快!
这是为什么?我的猜测是它与表锁定有关,但我不太了解或知道更多细节。
答案 0 :(得分:1)
因为SELECT *
包含last_seen
MySQL无法缓存查询或子查询。您可以尝试显式枚举除last_seen
之外的所有字段。
(但是单独的表格online_users
非常有意义。)
答案 1 :(得分:0)
假设SELECT
查询在测试之前运行了好几次,您很可能会看到查询缓存的影响。表上的任何更新都将使缓存无效,并强制再次执行查询。通过更新不同的表,您可以避免破坏这些缓存条目。
答案 2 :(得分:-4)
查询比MyISAM慢。 表中的更多行使查询更慢。 表上的错误索引使查询更慢,请使用EXPLAIN命令检查。