【问题标题】:mysql query slow down when using group by and order by in a same query在同一查询中使用 group by 和 order by 时,mysql 查询会变慢
【发布时间】:2011-11-25 07:16:58
【问题描述】:

我是 mysql 的初学者。我必须从表视图中获取查看次数最多的 contentid(过去 120 小时)。视图表包含 200,000(十万)条记录。我已索引 contentid 列,但我的查询需要 10 秒才能获取结果。

Views 表结构如下:

contentid viewed                ip
155     2011-10-26 00:07:52     216.251.77.226
1150    2011-10-26 00:08:15     65.52.109.72
1134    2011-10-26 00:08:30     178.53.54.221
14      2011-10-26 00:08:49     178.53.54.221
693     2011-10-26 00:08:58     115.184.174.136
433     2011-10-26 00:09:14     66.249.71.138
558     2011-10-26 00:09:26     91.83.214.3
715     2011-10-26 00:16:01     128.171.36.161
226     2011-10-26 00:16:06     110.36.39.102
562     2011-10-26 00:16:51     84.3.173.188
1134    2011-10-26 00:16:53     110.39.67.139
198     2011-10-26 00:16:57     220.227.133.163
155     2011-10-27 05:43:59     64.135.215.142
155     2011-10-27 08:39:46     157.55.39.86
155     2011-10-27 11:23:05     99.55.166.146
155     2011-10-27 15:40:29     174.255.241.202
1150    2011-10-26 00:50:50     119.30.96.83
1150    2011-10-26 01:02:58     66.249.71.138
1150    2011-10-26 08:02:31     95.144.197.55
1132    2011-10-26 00:16:07     119.160.126.99

我的查询是

SELECT contentid FROM views 
where viewed > DATE_SUB(NOW(), INTERVAL 120 HOUR) 
GROUP BY contentid ORDER BY count(contentid ) desc limit 0, 15

【问题讨论】:

  • 尝试运行EXPLAIN $your_query;你也可以查看mysqlperformanceblog.com/2006/09/01/…
  • 这里只是一个猜测,也许 date_sub 需要花费大量时间来计算每个值,而不是您可以尝试添加一个包含自 unix 纪元以来的秒数的新字段,例如 php 中的 time(),然后将 where 更改为 new_field > 120 * 3600 120 小时。
  • 你的桌子上有什么索引? EXPLAIN 显示了什么?
  • @ypercube :解释显示 - type=range, possible_keys=viewed, key=viewed,key_len=4, ref=null,rows=73440,Extra=Using where;使用临时的;使用文件排序
  • 所以查询使用了(viewed) 索引。尝试添加(contentid, viewed) 索引。我认为这将导致更快的性能。 (但不能保证,这取决于您的表格分布)

标签: mysql group-by sql-order-by


【解决方案1】:

我认为这个查询的好索引可以是viewed 上的简单索引或(contentid, viewed) 上的复合索引。


您还应该将COUNT(contentid) 更改为COUNT(*)

SELECT contentid FROM views 
WHERE viewed > DATE_SUB(NOW(), INTERVAL 120 HOUR) 
GROUP BY contentid 
ORDER BY COUNT(*) DESC 
LIMIT 0, 15

【讨论】:

  • 谢谢 ypercube。对查看的列进行索引可加快查询执行速度。
【解决方案2】:

我有一个理解,这可能是错误的,Now() 函数会为每一行调用,为什么不调用一次该函数并保存结果并在查询中使用结果。

尝试在viewed 列上添加索引,这样mysql 可能不必去表。执行此查询所需的所有数据都将在索引文件中提供。

【讨论】:

  • 感谢您的解决方案。你说的我已经试过了。但这并没有什么大的区别。
  • @nithi 请再看一个建议。
猜你喜欢
  • 2021-11-17
  • 1970-01-01
  • 1970-01-01
  • 2019-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多