在大型mysql表中找到每个不同的其他值出现次数最多的值的有效方法[关闭]

Posted

技术标签:

【中文标题】在大型mysql表中找到每个不同的其他值出现次数最多的值的有效方法[关闭]【英文标题】:Efficient way to find value that occurs the most times with each distinct other value, in large mysql table [closed] 【发布时间】:2021-03-03 18:38:33 【问题描述】:

我有一个大约 6100 万行的 mysql 表。我对此问题感兴趣的两列是“foo_type”和“foo_id”。我想要做的是,对于“foo_type”的每个不同值,返回出现次数最多的 foo_id。

所以,我的结果将如下所示:

foo_type  |  foo_id
-------------------
Banana    |  127321
Apple     |  59871
etc

等,意思是“当 foo_type 为 'Apple' 时,foo_id 59871 出现的次数比 foo_id 的任何其他值都多。”

这两列都使用一个多列索引(仅涵盖这两列)进行索引。

最有效的方法是什么?谢谢

编辑:我提前知道 foo_type 的所有可能值是什么,如果有帮助的话。

【问题讨论】:

请看Why should I provide an MCRE for what seems to me to be a very simple SQL query @Strawberry 在这种情况下,MCRE 很困难,因为这完全是关于如何处理非常大的数据集。我可以给出一个有 100 行的样本,但是对于那个效率问题将是无关紧要的。只有当表格非常大时,这个问题的好坏答案才会真正适用。 这个社区中有很多人足够聪明,可以自然地提供最有效的解决方案(受基数、索引等限制) 【参考方案1】:

您正在描述一个称为模式的统计概念。一些数据库有一个内置的聚合函数(例如 Oracle),但没有 MySQL。

您可以使用聚合和窗口函数来解决这个问题:

select *
from (
    select foo_type, foo_id, count(*) cnt, 
        rank() over(partition by foo_type order by count(*) desc) rn
    from mytable 
) t
where rn = 1

这需要 MySQL 8.0。在早期版本中:

select foo_type, foo_id, count(*) cnt
from mytable t
group by foo_type, foo_id
having count(*) = (
    select count(*)
    from mytable t1
    where t1.foo_type = t.foo_type
    group by t1.foo_id
    order by count(*) desc limit 1
)

【讨论】:

谢谢 - 我在本地版本上运行它,大约是生产版本大小的 1/200(以该表中的行数计),15 分钟后它仍在运行。我希望有更快的方法... @MaxWilliams 。 . .在一个有 200 万行(甚至 6000 万行)的表上,这些查询都不应该花费 15 分钟。其他东西可能会降低您的系统速度。

以上是关于在大型mysql表中找到每个不同的其他值出现次数最多的值的有效方法[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

计算每个值在 PostgreSQL 表中出现的次数?

计数值出现在 MySQL 中特定列中的次数

THINKPHP怎么查询一张表中某个字段数据重复次数最多的前几名!

Python:计算python数据框中每个数字的出现次数

在 XSLT 中,如何计算给定属性值的每个不同值出现在输入 XML 中的次数?

Transact-SQL计算整个表中所有值的出现的次数