【问题标题】:Mysql Very Slow Performance Using Order by ClauseMysql 使用 Order by Clause 性能非常慢
【发布时间】:2018-08-03 16:16:06
【问题描述】:

我有一张表,有数百万个条目。下面是表结构。

CREATE TABLE `useractivity` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
 `userid` bigint(20) NOT NULL,
 `likes` bigint(20) DEFAULT NULL,
 `views` bigint(20) DEFAULT NULL,
 `shares` bigint(20) DEFAULT NULL,
 `totalcount` bigint(20) DEFAULT NULL,
 `status` bigint(20) DEFAULT NULL,
 `createdat` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `userid` (`userid`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

下面是我的性能下降的查询。

SELECT userid, 
 (sum(likes)+SUM(views)+SUM(shares)+SUM(totalcount)+SUM(`status`)) as total
from useractivity
GROUP BY userid
ORDER BY total DESC
limit 0, 20;

当我在没有 ORDER BY 的情况下执行上面的查询时,它会给我快速的结果集但是当使用 ORDER BY 时,这个查询变得很慢,尽管我使用了分页限制。

我可以做些什么来加快这个查询?

【问题讨论】:

  • 我认为您对此无能为力。引擎必须读取所有行,然后对所有用户进行排序。我看到的唯一方法是创建一个汇总表。
  • order-by 将使它必须查看每个匹配的行来计算出顺序,这需要更多的工作,在此排序之后应用限制。
  • @AlexK.,是的,排序完成后,应用限制。还有其他可以写查询以便我加快速度吗?
  • 请不要cross post

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


【解决方案1】:

您无法按原样加快查询速度,MySQL 需要访问每一行并计算总和,然后再排序并最终返回第一行。这势必需要时间。不过你可能会作弊。

最明显的方法是创建一个包含用户 ID 和总计的汇总表。在基表更改或定期重新计算时更新它,只要有意义。在该表中,您可以索引总计,这使得查询变得微不足道。

另一种选择可能是查找排名靠前的用户。大多数网站的用户都比其他网站更活跃。将前 1000 个顶级用户保存在单独的表中,然后使用相同的选择,但仅用于顶级用户(即加入该表)。只需要访问顶级用户的用户活动行,这应该很快。如果 1000 个用户还不够,也许 10000 个作品。

【讨论】:

    猜你喜欢
    • 2019-08-21
    • 1970-01-01
    • 1970-01-01
    • 2013-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多