簡體   English   中英

SQL 查詢按 ID 分組的行計數,但限制每組的計數

[英]SQL query to count rows grouped by an ID, but limit count on each group

所以我有一個不尋常的要求。 我正在處理一個有數十億行的表。

該表有一列“id”不是唯一的,並且有一列“數據”

我想要做的是對按“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上有一個索引並且只想要具有 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 行。 如果它不存在,則不返回任何行。

我不認為這是可能的。 必須掃描整個表才能知道哪些id至少有 150 個條目。

所以:

select id
from mytable
group by id
having count(*) >= 150

使用id上的索引,這應該盡可能高效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM