【问题标题】:The same query on the same MySQL database take different time to be executed在同一个 MySQL 数据库上执行相同的查询需要不同的时间来执行
【发布时间】:2020-08-30 02:13:38
【问题描述】:

我有一个 PhpBB 板,有大约 3000 名用户和 500.000 个帖子。在最后几天,我注意到某些主题的打开时间比标准时间长(大约 2 秒而不是 0.05 秒)。 所以我做了一个调试来调查,我发现这是一个查询错误。执行相同的查询需要不同的时间,具体取决于它请求的主题。 例如这个查询需要 1.7011 秒来执行:

SELECT u.username, u.user_id, u.user_active, u.user_mask, u.user_color, u.user_first_name, u.user_last_name, u.user_posts, u.user_from, u.user_long, u.user_lat, u.user_from_flag, u.user_website, u.user_email, u.user_aim, u.user_facebook, u.user_flickr, u.user_googleplus, u.user_icq, u.user_jabber, u.user_linkedin, u.user_msnm, u.user_skype, u.user_twitter, u.user_yim, u.user_youtube, u.user_regdate, u.user_allow_viewemail, u.user_rank, u.user_rank2, u.user_rank3, u.user_rank4, u.user_rank5, u.user_sig, u.user_avatar, u.user_avatar_type, u.user_allowavatar, u.user_allowsmile, u.user_allow_viewonline, u.user_session_time, u.user_warnings, u.user_level, u.user_birthday, u.user_next_birthday_greeting, u.user_gender, u.user_personal_pics_count, u.user_style, u.user_lang, u.preferenza_meteo, u.stazione_meteo, u.ct_miserable_user, p.*, t.topic_poster, t.title_compl_infos
FROM phpbb_posts p, phpbb_users u, phpbb_topics t
WHERE p.topic_id = 17278
AND t.topic_id = p.topic_id
AND u.user_id = p.poster_id
ORDER BY p.post_time ASC
LIMIT 0, 15

这是 EXPLAIN 结果:

这个查询,虽然是一样的,但是在WHERE子句中使用了不同的ID主题,耗时0.0015秒,这是这种DB请求的正常时间。

SELECT u.username, u.user_id, u.user_active, u.user_mask, u.user_color, u.user_first_name, u.user_last_name, u.user_posts, u.user_from, u.user_long, u.user_lat, u.user_from_flag, u.user_website, u.user_email, u.user_aim, u.user_facebook, u.user_flickr, u.user_googleplus, u.user_icq, u.user_jabber, u.user_linkedin, u.user_msnm, u.user_skype, u.user_twitter, u.user_yim, u.user_youtube, u.user_regdate, u.user_allow_viewemail, u.user_rank, u.user_rank2, u.user_rank3, u.user_rank4, u.user_rank5, u.user_sig, u.user_avatar, u.user_avatar_type, u.user_allowavatar, u.user_allowsmile, u.user_allow_viewonline, u.user_session_time, u.user_warnings, u.user_level, u.user_birthday, u.user_next_birthday_greeting, u.user_gender, u.user_personal_pics_count, u.user_style, u.user_lang, u.preferenza_meteo, u.stazione_meteo, u.ct_miserable_user, p.*, t.topic_poster, t.title_compl_infos
FROM phpbb_posts p, phpbb_users u, phpbb_topics t
WHERE p.topic_id = 17250
AND t.topic_id = p.topic_id
AND u.user_id = p.poster_id
ORDER BY p.post_time ASC
LIMIT 0, 15

这是此查询的 EXPLAIN 结果:

我使用这个板大约 15 年了,我从来没有注意到类似的问题,以及类似的打开话题的时间。但我无法理解问题可能出在哪里。

【问题讨论】:

  • 这可能是您的索引大小已经增长到不再适合内存的程度。在某些导致性能下降的 MySQL 版本上。
  • 考虑分析 3 个表中的每一个,然后重试。可能需要刷新索引统计信息。所有表都是 innodb 吗?
  • @WilsonHauck 不,所有表都是 MyISAM。对这 3 个表执行 ANALYZE 命令不会返回错误。
  • 现在已经用Analyze刷新了索引统计信息,这2个查询中的每一个需要多少时间?
  • 和之前一样……一慢一快。

标签: php mysql forum phpbb


【解决方案1】:

我解决了(我希望)在 INNODB 中转换 phpbb_posts 表而不是 MyISAM。我不知道这是否是最好的解决方案,但现在所有查询都可以快速运行并使用正确的 KEY INDEX。

我在第一篇文章中发布的第一个查询,以前需要 1.7011 秒才能执行,现在只需要 0.0017 秒。

这是 EXPLAIN 结果:

【讨论】:

    【解决方案2】:

    MySQL 使用内部缓存来处理您的请求。数据库中更频繁的部分在缓存中,而其他部分不在。多次执行相同的查询应该告诉您,第一次调用是,就查询和结果不在缓存中而言,最慢和连续调用变得更快。对数据库的更改会使缓存无效,因此您的查询可能会在下一次调用时变慢。

    第二点是连接。需要匹配的数据越多,查询运行的时间就越长。您可以在“行”列中的说明中看到这一点。您的第一个查询将探索表“p”的 1004 行,而第二个查询只有 476 行。

    【讨论】:

    • 正如@tadman 所说,缓存可能缺少内存。当您的服务器有足够的资源时,您可以增加它们以适应您的数据库。另一种方法是,您归档一些数据并减少帖子/线程的数量。不需要归档来删除数据,但会减少应该在缓存中的主表的大小。存档也可以被读取,但应该是未缓存且速度慢的。但是我不知道PHPBB有这样的功能。
    • 我会调查缓存内存,因为我不认为这只是一个简单的缓存问题,因为即使在一些调用之后,相同的主题也需要相同的时间,即使没有添加新帖子也可能会失效缓存。关于第二点,即使是次要行,我也会获得很长时间i.stack.imgur.com/yNWRz.png
    • 我注意到的是,在慢速查询中,使用的 KEY INDEX 是不同的。尝试检查 KEY 列中的图像。
    • 是的,mysql 优化器检测到,这个键应该是最适合查询的。这取决于表中预期的数据大小。您在查询中使用表 p 中的 3 个字段,因此一种可能的解决方案可能是创建一个匹配更好的索引,并且可以用于 2 个或所有字段。但要小心:创建新索引会增加索引内存的大小和写入表的时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-23
    • 1970-01-01
    • 2021-09-23
    • 1970-01-01
    • 1970-01-01
    • 2014-03-23
    • 1970-01-01
    相关资源
    最近更新 更多