繁体   English   中英

MySQL:查询前n个聚合

[英]MySQL: query the top n aggregations

我有一个表,用于计算不同用户对不同对象的一个​​特定操作的出现次数:

CREATE TABLE `Actions` (
    `object_id` int(10) unsigned NOT NULL,
    `user_id` int(10) unsigned NOT NULL,
    `actionTime` datetime
);

每次用户执行此操作时,都会插入一行。 我可以计算对每个对象执行了多少操作,并按“活动”对对象进行排序:

SELECT object_id, count(object_id) AS action_count 
FROM `Actions` 
GROUP BY object_id 
ORDER BY action_count;

如何将结果限制为前n个对象? LIMIT子句在聚合之前应用,因此会导致错误的结果。 该表可能很大(数百万行),我可能需要每分钟数十次,所以我希望尽可能高效地完成这项工作。

编辑 :实际上,机器是正确的,我在应用LIMIT的时候错了。 我的查询返回了正确的结果,但是向我展示的GUI让我失望......这种问题使得这个问题毫无意义。 抱歉!

实际上......在最终的HAVING子句之后,LIMIT最后应用。 所以它不应该给你不正确的结果。 但是,由于LIMIT最后应用,它不会提供任何更快的查询执行,因为在切断结果之前,必须按行动计数的顺序创建临时表并对其进行排序。 另外,请记住按降序排序:

SELECT object_id, count(object_id) AS action_count 
FROM `Actions` 
GROUP BY object_id 
ORDER BY action_count DESC
LIMIT 10;

您可以尝试向object_id添加索引以进行优化。 这样,只需要扫描索引而不是Actions表。

我知道这个帖子已经有2年了,但是stackflow仍然发现它有用,所以这里的价格为0.02美元。 ORDER BY子句在计算上非常昂贵,因此在大型表中应避免使用它们。 我使用的一个技巧(部分来自Joe Celko的SQL for Smarties)是这样的:

SELECT COUNT(*) AS counter, t0.object_id FROM (SELECT COUNT(*), actions.object_id FROM actions GROUP BY id) AS t0, (SELECT COUNT(*), actions.object_id FROM actions GROUP BY id) AS t1 WHERE t0.object_id < t1.object_id  GROUP BY object_id HAVING counter < 15

将为您提供前15个编辑对象而无需排序。 请注意,从v5开始,mysql将仅缓存完全重复(空白包含)查询的结果集,因此嵌套查询不会被缓存。 使用视图可以解决该问题。

是的,这是三个查询而不是两个,唯一的好处是不必对分组查询进行排序,但如果你有很多组,它会更快。

旁注:对于没有排序的中值函数,查询非常方便

怎么样:

SELECT * FROM
(
SELECT object_id, count(object_id) AS action_count 
FROM `Actions` 
GROUP BY object_id 
ORDER BY action_count
)
LIMIT 15

此外,如果您有一些必须包含的最小操作数量(例如前n个肯定超过1000),您可以通过添加HAVING子句来提高效率:

SELECT * FROM
(
SELECT object_id, count(object_id) AS action_count 
FROM `Actions` 
GROUP BY object_id 
HAVING action_count > 1000
ORDER BY action_count
)
LIMIT 15
SELECT * FROM (SELECT object_id, count(object_id) AS action_count 
        FROM `Actions` 
        GROUP BY object_id 
        ORDER BY action_count) LIMIT 10;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM