gpt4 book ai didi

mysql - SQL查询以计算按ID分组的行,但限制每个组的计数

转载 作者:行者123 更新时间:2023-11-29 04:32:12 25 4
gpt4 key购买 nike

所以我有一个不寻常的请求。我正在处理一个包含数十亿行的表。

该表有一个不唯一的“id”列,还有一个“data”列

我想做的是对按“id”分组的行数进行计数,但将计数限制为仅 150 个条目。我只需要知道任何给定 ID 是否有 150 行。

这是为了优化查询和性能。

它不一定是计数。我只需要知道给定的 id 是否有 150 个条目,而不需要 MySQL 在查询期间继续计算条目。如果这是有道理的话。

我知道如何计数,我知道如何分组,我知道如何两者兼顾,但计数将返回数百万,这浪费了处理时间,查询需要在数百上运行数千个 ID。

最佳答案

您无法为此真正优化性能——我不认为。

select id, (count(*) >= 150)
from t
group by id;

如果您碰巧有一个单独的表,每个 id 一行,t(id) 上有一个索引,那么这可能会更快:

select ids.id,
((select count(*)
from t
where t.id = ids.id
) >= 150
)
from ids;

不幸的是,MySQL 不支持相关子查询的双重嵌套,所以这是不可能的:

select ids.id,
((select count(*)
from (select 1
from t
where t.id = ids.id
limit 150
) t
) >= 150
)
from ids;

如果是这样,这可能会更快。

编辑:

如果您在 id 上有一个索引并且只想要 id 有 150 或更多,那么变量可能会更快:

select id,
(@rn := if(@id = id, @rn + 1,
if(@id := id, 1, 1)
)
) as rn
from (select id
from t
order by id
) t cross join
(select @id := 0, @rn := 0) params
having rn = 150;

这里的思路是用索引对表进行排序,物化,再扫描,大概比group by要快。我认为 row_number() 不会具有相同的性能特征。

编辑二:

上面的一个细微变化可用于获取所有带有标志的 id:

select id, (max(id) = 150)
from (select id,
(@rn := if(@id = id, @rn + 1,
if(@id := id, 1, 1)
)
) as rn
from (select id
from t
order by id
) t cross join
(select @id := 0, @rn := 0) params
having rn in (1, 150)
) t
group by id;

编辑三:

啊!如果您有一个单独的 ID 表,那么这可能是最好的方法:

select ids.id,
(select id
from t
where t.id = ids.id
limit 1 offset 149
) is not null
from ids;

这将从索引中获取第 150 行。如果不存在,则不会返回任何行。

关于mysql - SQL查询以计算按ID分组的行,但限制每个组的计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58866652/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com