繁体   English   中英

Select 行在大表中具有唯一值的特定列

[英]Select rows with unique values for one specific column in large table

table1在我的数据库中有 3 列: idtimestampcluster ,它有大约 1M 行。 我想用唯一的集群值查询最新的 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 行具有唯一聚类值的行。 这个查询运行得更快(~.007 秒)。 现在我想问这种情况有没有更有效/常规的方法?

您假设在最后 50 行中您会发现 24 个不同的集群可能不正确。

尝试使用ROW_NUMBER() window function:

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

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

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;

您想要的索引在(cluster, timestamp 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 小时内的行。

由于您想要“一个特定的集群值”,这将很快:

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

并且有

INDEX(cluster, timestamp)

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM