Mysql 为大表中的一个特定列选择具有唯一值的行

Mysql 为大表中的一个特定列选择具有唯一值的行,mysql,sql,Mysql,Sql,table1在我的数据库中有3列:id,timestamp,cluster,它大约有100万行。我想用唯一的集群值查询最新的24行(返回的24行中没有一行必须有重复的集群值)。通常的解决办法是: SELECT * FROM table1 GROUP BY cluster ORDER BY timestamp DESC LIMIT 24 然而,由于我有1M行,这个查询需要很长时间才能执行。因此,我的解决方案是运行: WITH x AS ( SELECT *

table1
在我的数据库中有3列:
id
timestamp
cluster
,它大约有100万行。我想用唯一的集群值查询最新的24行(返回的24行中没有一行必须有重复的集群值)。通常的解决办法是:

SELECT
    *
FROM table1
GROUP BY cluster
ORDER BY timestamp DESC
LIMIT 24
然而,由于我有1M行,这个查询需要很长时间才能执行。因此,我的解决方案是运行:

WITH x AS
(
    SELECT
        *
    FROM `table1`
    ORDER BY timestamp DESC
    LIMIT 50
)
SELECT
    *
FROM x
GROUP BY x.cluster
ORDER BY x.timestamp DESC
LIMIT 24

假设每50行中可以找到24行具有唯一群集值。此查询的运行速度要快得多(约0.007秒)。现在我想问,对于这种情况,有没有更有效/常规的方法?

您认为在最后50行中,您将发现24个不同的集群可能是不正确的。

尝试使用
行编号()
窗口功能:

SELECT *
FROM (
  SELECT *, ROW_NUMBER() OVER (PARTITION BY cluster ORDER BY timestamp DESC) rn
  FROM table1
) t
WHERE rn = 1
ORDER BY timestamp DESC LIMIT 24

您可以使用
行编号()
,但需要正确的索引:

select t.*
from (select t.*,
             row_number() over (partition by cluster order by timestamp desc) as seqnum
      from t
     ) t
where seqnum = 1
order by timestamp desc
limit 24;
您想要的索引位于
(集群,时间戳desc)

出于您的目的,这可能仍然不够,因为它仍然在处理所有的行,即使有索引,而您只需要几十行

我不知道最近需要多少行来确保有24个集群。但是,如果我们假设最近1000行至少有24个集群,您可能会发现这样做效果更好:

select t.*
from (select t.*,
             row_number() over (partition by cluster order by timestamp desc) as seqnum
      from (select t.*
            from t
            order by timestamp desc
            limit 1000
           ) t
     ) t
where seqnum = 1
order by timestamp desc
limit 24;
为此,您只需要
(timestamp desc)
上的索引

注意:您可能会发现时间戳上的
where
子句在这种情况下效果更好:

where timestamp > now() - interval 24 hour

例如,只考虑过去24小时的行。

< P>因为您想要“一个特定的簇值”,这将是很快的:

SELECT
    *
FROM table1
WHERE cluster = ?
ORDER BY timestamp DESC
LIMIT 24
而且

INDEX(cluster, timestamp)

如果这不是你想要的,请改写标题和问题。

。您将
select*
groupby
一起使用的SQL格式不正确。它应该生成一个编译器错误。问题的标题是:……对于一个特定的列,而不是一个特定的集群,我仍然感到困惑。提供一些样本数据和样本结果(可能仅限3个)。