我有一个包含一堆事件的 PostgreSQL 表,每个事件都包含时间戳、id 和操作。我预计每天会发生几百万个事件,并预计该表最终会增长到数十亿行。
我想查询给定日期之前每个 id(几十万个不同 id)的最新事件,但目前查询速度非常慢,至少需要 1-2 小时(该表目前约有 1 亿行)。有没有办法加快这个查询速度?
SELECT a.* FROM (
with events as (
SELECT
ROW_NUMBER() OVER (PARTITION BY item ORDER BY time_stamp DESC) AS rn,
*
FROM event_updates
WHERE time_stamp < '2023-05-01'
)
SELECT * FROM events WHERE rn=1 ORDER BY item
) a;
表的DDL
CREATE TABLE "event_updates" (
"id" int4 NOT NULL DEFAULT nextval("event_updates"::regclass),
"time_stamp" timestamptz(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"item" varchar(32) COLLATE "pg_catalog"."default" NOT NULL,
"event_type" int2,
)
PARTITION BY ();
ALTER TABLE "event_updates" OWNER TO "owners";
首先,您需要一个项目索引和时间戳。其次,您为每个项目选择最大值(时间戳),然后选择您需要的记录:
CREATE INDEX idx_event_updates_item_time_stamp
ON event_updates(item, time_stamp);
SELECT *
FROM event_updates
JOIN (SELECT item
, MAX(time_stamp) time_stamp
FROM event_updates
GROUP BY item
) sub USING (item, time_stamp);
您可能希望同时为每个分区创建索引,以避免锁定问题。不过需要更长的时间。