你无法真正优化性能——我不这么认为。
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 上有一个索引并且只想要具有 150 或更多的 id,那么变量可能会更快:
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 行。如果不存在,则不返回任何行。