【问题标题】:Best way to sort by AVG and COUNT in MySql在 MySql 中按 AVG 和 COUNT 排序的最佳方法
【发布时间】:2012-09-11 17:42:57
【问题描述】:

我正在研究一个简单的评级系统,正如我所问的Here

数据是半大的(10 万条记录),我有一个具有这种结构的速率表:

CREATE TABLE IF NOT EXISTS `rates` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `rate` int(10) unsigned NOT NULL DEFAULT '0',
  `ip` int(10) unsigned DEFAULT NULL,
  `imageid` int(10) unsigned NOT NULL DEFAULT '0',
  `sdate` date DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `imageid` (`imageid`)
)

它存储每个图像的用户率。如您所见,我只有一个用于该表的键(imageid),用于另一个查询中的 OUTER JOIN...

但在这个没有任何 JOIN 的简单查询中,我也有问题:

SELECT r.imageid,COUNT(r.id) as cnt,AVG(r.rate) AS arate,MAX(r.sdate) as lastdate  FROM rates r  GROUP BY r.imageid 
ORDER BY
arate DESC, cnt DESC,lastdate DESC

解释说查询是使用临时的;使用文件排序。在我的大型数据库中,这是一个问题,这个问题蔓延到我的主要 JOIN 查询。

有没有什么方法可以在不排序的情况下获得字段的最高平均值? (按AVG排序,不能使用索引)

【问题讨论】:

    标签: mysql optimization indexing


    【解决方案1】:

    各种统计数据的共同优化 - 是预先计算。

    当您需要 100% 的实际平均值时,这是非常罕见的。因此,只需将其预先计算到另一个表并立即获得结果。

    实际状态可以通过触发器或调度来维护。

    【讨论】:

    • @MscEliot:您创建单独的表,计算所有COUNTAVG 等并保留在那里。之后,您将使用预先计算的数据。并根据需要经常刷新它
    【解决方案2】:

    我的意见 - 在表格图像中使用 - 字段 sum_rates 和 count_rates 以及每个比率 - 将 rate 添加到 sum_rates 并将 +1 添加到 count_rates。

    如果你需要得到平均费率,你可以这个选择

    select (sum_rates / count_rates)
    from images
    

    这个查询必须工作得更好。

    【讨论】:

    • 是的,你是对的,我打算这样做,但在我的系统中,我需要一天、一周、一个月的顶部......!换句话说,我想在不同的日子里获得最高的平均值。您的解决方案从一开始就给出了总平均值!
    • 当您想使用有限的 top 计数时 - 您可以使用额外的临时表并在一天(6 小时、1 小时等)内(通过)cron 计算这个 top 一次。不幸的是,索引不支持像 AVG 这样的聚合函数。
    猜你喜欢
    • 1970-01-01
    • 2015-11-17
    • 1970-01-01
    • 2013-09-14
    • 2014-05-30
    • 1970-01-01
    • 1970-01-01
    • 2012-09-23
    • 2021-01-04
    相关资源
    最近更新 更多