【问题标题】:MySQL groupwise maximum performance issues on a million row table一百万行表上的 MySQL groupwise 最大性能问题
【发布时间】:2012-07-27 10:12:19
【问题描述】:

我正在尝试找到一种直接的方法来提高非常活跃的论坛的性能,其中有大量帖子,mysql 不能再在内存中进行表排序并且似乎没有充分利用索引。

这个简单的查询查找每个主题中的最新帖子,以便用户确定他们是否有任何回复(通过稍后比较主题时间)

SELECT p.*, MAX(post_time) as post_time FROM forum_posts AS p   
WHERE p.poster_id = '1' AND p.post_status = '0' 
GROUP BY p.topic_id  
ORDER BY post_time DESC 
LIMIT 50

简单,扁平的桌子看起来像

post_id | poster_id | topic_id | post_status | post_time | post_text

但是,当有一百万个帖子并且用户自己有数万个帖子时,它的性能就会崩溃。 MySQL 要么不再对内存中的表进行排序,要么扫描的行太多。在实际使用中最多可能需要 3 秒,恕我直言,这是不可接受的,因为在此期间它会占用 CPU 并减慢其他所有人的速度。

我当然可以做任何索引的组合,但是mysql似乎最喜欢使用组合

poster_id + post_time 

所以它只是从百万中选择一个用户的 50k 帖子,然后开始按 topic_id 分组和排序。奇怪的是,将 topic_id 添加到索引组合中似乎对性能没有帮助,尽管它可能是索引字段的顺序?

我尝试编写一个等效的 JOIN,以便可以使用多个索引,但我遇到了问题,即每一边都必须由 post_status 和 poster 过滤。

我认为它会更快,至少对于前几页来说,如果 mysql 可以首先通过它的索引按 post_time 对数据进行排序,然后开始为用户挑选不同的 topic_id 降序命令。我想这将需要一个子查询,并且不确定 50k 结果子查询会更好,仍然需要一个临时表。

当然,一个基本的解决方案是增加核心设计,以便有另一个表只存储每个主题中每个用户的最大 post_time,但除非找不到其他解决方案,否则这变化太大了。

感谢您的任何建议!


添加真实世界的示例并说明:

慢日志

# Query_time: 2.751334  Lock_time: 0.000056 Rows_sent: 40  Rows_examined: 48286
SELECT   p.*, MAX(post_time) as post_time FROM forum_posts AS p   WHERE p.poster_id = '2' AND p.post_status = '0' GROUP BY p.topic_id  ORDER BY post_time DESC LIMIT 7000, 40;

解释

select_type     table   type    possible_keys   key     key_len     ref     rows    Extra
SIMPLE          p   ref poster_time poster_time 4   const   27072   Using where; Using temporary; Using filesort

【问题讨论】:

标签: mysql groupwise groupwise-maximum


【解决方案1】:

首先,修复您的查询以提供确定的结果:

SELECT p.topic_id, 
       MAX(post_time) as post_time 
FROM forum_posts AS p   
WHERE p.poster_id = '1' AND p.post_status = '0' 
GROUP BY p.topic_id  
ORDER BY post_time DESC 
  LIMIT 50 ;

然后在(post_status, poster_id, topic_id, post_time)上添加索引后试试。

【讨论】:

  • 对于它的价值,我没有创建原始查询,它是一个现有的论坛程序。但是我使用了您方法的修改版本,通过针对原始查询的复杂过滤器来解决问题 - 您肯定让我走上了正确的轨道,谢谢。查询时间现在在 100-300 毫秒范围内,而不是 1000-3000 毫秒
猜你喜欢
  • 2023-03-31
  • 2012-07-10
  • 2017-07-29
  • 2010-11-10
  • 1970-01-01
  • 2016-05-02
  • 2019-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多