当我这样做时,为什么我的MySQL查询速度很快,而当我这样做时,它的速度会变慢?

时间:2012-01-20 04:09:45

标签: mysql sql

我需要跟踪在我网站上在线的用户,这样我就可以在在线用户的头像旁边显示“在线”图标。

检测到这一点的第一步是跟踪用户上次看到的时间,这样每次用户请求页面时我都会进行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

并且页面加载速度更快!

这是为什么?我的猜测是它与表锁定有关,但我不太了解或知道更多细节。

3 个答案:

答案 0 :(得分:1)

因为SELECT *包含last_seen MySQL无法缓存查询或子查询。您可以尝试显式枚举除last_seen之外的所有字段。

(但是单独的表格online_users非常有意义。)

答案 1 :(得分:0)

假设SELECT查询在测试之前运行了好几次,您很可能会看到查询缓存的影响。表上的任何更新都将使缓存无效,并强制再次执行查询。通过更新不同的表,您可以避免破坏这些缓存条目。

答案 2 :(得分:-4)

innoDB表上的

查询比MyISAM慢。 表中的更多行使查询更慢。 表上的错误索引使查询更慢,请使用EXPLAIN命令检查。