我有这个表- 'product-usage‘。此表中的列为id、rank、product_id、checked_at (时间戳)。我正在尝试将另一个名为'last_inactive‘的列(时间戳)添加到这个表中,并回溯填充该列。这样做的逻辑是: 1)为同一product_id的下一个条目找到created_at (按等级排序) 2)获取该时间戳并减去1秒,然后使用该时间戳填充当前列,然后继续3)如果下一行不存在,则使用now()作为last_inactive的值
为了得到想要的结果,我尝试了以下几种方法
SELECT *,
coalesce(
date_sub(
(SELECT checked_at
FROM product_usage p2
WHERE p2.rank > p.rank
and p.product_id=p2.product_id
group by id, product_id, created_at
ORDER BY product_id, rank ASC
LIMIT 1 OFFSET 0),
INTERVAL 1 second),
now()
)
as valid_until
FROM product_usage p
where p.product_id = '1111111';
这个查询适用于这个特定的product_id,但每个product_id需要大约2-3秒的时间,并且我希望这个查询适用于大约20k个不同的product_ids。有什么我可以做的让它更快吗?
发布于 2019-06-29 01:53:37
子查询中不需要聚合。所以试试这个:
SELECT pu.*,
coalesce(date_sub( (SELECT pu2.checked_at
FROM product_usage pu2
WHERE pu2.rank > pu.rank AND
pu2.product_id = pu.product_id
ORDER BY pu2.rank ASC
LIMIT 1 OFFSET 0
), INTERVAL 1 second
), now() ) as valid_until
FROM product_usage pu
WHERE pu.product_id = 1111111; -- looks like a number so removed the single quotes
因此,您需要在product_usage(product_id, rank, created_at)
上建立一个索引。
当然,在MySQL 8+中,您只需使用lead()
。
https://stackoverflow.com/questions/56811253
复制相似问题