[英]Select rows with unique values for one specific column in large table
table1
在我的数据库中有 3 列: id
、 timestamp
、 cluster
,它有大约 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.