【发布时间】:2017-02-10 11:00:23
【问题描述】:
我正在尝试根据导入时使用的 TIMESTAMPZ 返回商店的最新记录。我在 Postgres 9.5 上,这是我从这里的一些线程的 stackoverflow 中得到的查询:
select p.*
from store_products p
inner join(
select storeid, sku, max(lastupdated) AS lastupdated
from store_products
group by storeid, sku
)sp on p.storeid= sp.storeidand p.lastupdated = sp.lastupdated
这为我提供了每家商店(和 SKU)的最新产品,这很棒(我们有大约 30 家商店),但我注意到查询需要(600 万条记录) 4分钟收集数据。
因此,如果我们将其作为我的数据:
PID | StoreID | SKU | lastupdated
1 | 1 | 1a1 | 2017-02-02 18:22:30
2 | 1 | 1b1 | 2017-02-02 18:21:30
3 | 1 | 1a1 | 2017-01-16 11:22:30
4 | 2 | 1a1 | 2017-02-02 18:21:30
5 | 2 | 1a1 | 2017-02-01 18:21:00
6 | 3 | 1a1 | 2017-02-02 18:21:30
7 | 3 | 1g1 | 2017-02-01 18:21:30
我明白了:
PID | StoreID | SKU | lastupdated
1 | 1 | 1a1 | 2017-02-02 18:22:30
2 | 1 | 1b1 | 2017-02-02 18:21:30
4 | 2 | 1a1 | 2017-02-02 18:21:30
6 | 3 | 1a1 | 2017-02-02 18:21:30
有没有更好的方法让我们能够导入这些商店快照,以便 Postgres 更容易消化上面的查询 - 更快?我们应该添加任何索引吗?这是解释:
Hash Join (cost=2358424.92..2715814.08 rows=311 width=371)
Hash Cond: ((lp.storeid = p.storeid) AND (lp.lastupdated = p.lastupdated))
-> Subquery Scan on lp (cost=1676046.30..1737513.85 rows=62125 width=12)
-> GroupAggregate (cost=1676046.30..1736892.60 rows=62125 width=108)
Group Key: store_products.storeid, store_products.sku
-> Sort (cost=1676046.30..1691102.56 rows=6022505 width=108)
Sort Key: store_products.storeid, store_products.sku
-> Seq Scan on store_products (cost=0.00..297973.05 rows=6022505 width=108)
-> Hash (cost=297973.05..297973.05 rows=6022505 width=371)
-> Seq Scan on store_products p (cost=0.00..297973.05 rows=6022505 width=371)
我们的 Postgres DBA 正在休假,我们中的大多数人并不真正知道在这里做什么。
背景故事...
我们以 JSON 格式获取来自多个商店的商店产品的每日转储。每个商店都由 storeid 确定,它们被导入为一个包含所有商店及其产品的大块 JSON 文件。每个条目都有自己的 lastupdated | TIMESTAMPZ 字段。如果有人决定稍后更新该字段(出于审计目的),这由触发器支持,以自动更新该字段。每天,有大约 2-3K 价值的 store_products 被插入到这个表中,我们目前没有对这些数据进行重复数据删除(所以价格可能已经改变,它可能没有,我们似乎并不关心,我们只是插入)。我想我们很快就会进行重复数据删除。
让我给你一个基本的架构:
CREATE TABLE store_products
(
id BIGINT DEFAULT PRIMARY KEY NOT NULL,
storeid INTEGER,
...etc etc...
lastupdated TIMESTAMP WITH TIME ZONE DEFAULT now()
);
storeid 有一个 FK 到 store 表等。
【问题讨论】:
-
"这给了我每家商店的最新产品,...但我真的需要每家商店的所有最新产品" - 我不明白这句话。每个商店只能有一个“最新”产品。请Edit您的问题并添加一些示例数据和基于该数据的预期输出。 Formatted text 请no screen shots 你检查了greatest-n-per-group 的许多答案吗
-
会做的,谢谢@a_horse_with_no_name 我会的,是的,这句话有点不对劲......我会用一些样本来修复它,并在查看了我想出的每组最大的数之后上面的查询。我认为我的情况有点不同,因为不幸被 tiemstamp 分开
标签: database postgresql timestamp greatest-n-per-group