I have this table in PostgreSQL 13:
CREATE TABLE candles (
id serial primary key,
day integer,
minute integer,
"open" integer,
high integer,
low integer,
"close" integer,
volume integer,
id_d1 integer,
);
CREATE INDEX candles_idx1 ON public.candles (day,minute);
I try to update field id_d1
which should have id
of previous day on the same hour:
UPDATE candles s2
SET id_d1 = (SELECT id FROM candles s
WHERE s.id<s2.id
AND s.day<s2.day
AND s.minute=s2.minute
ORDER BY s.id DESC
LIMIT 1);
For smaller amount of data it works well. For 80k records it runs endlessly.
EXPLAIN the query:
Update on candles s2 (cost=0.00..744027.57 rows=80240 width=68)
-> Seq Scan on candles s2 (cost=0.00..744027.57 rows=80240 width=68)
SubPlan 1
-> Limit (cost=0.29..9.25 rows=1 width=4)
-> Index Scan Backward using candles_pkey on candles s (cost=0.29..2347.34 rows=262 width=4)
Index Cond: (id < s2.id)
Filter: ((day < s2.day) AND (minute = s2.minute))
I also tried (no id in WHERE clause):
EXPLAIN
UPDATE candles s2
SET id_d1 = (SELECT id FROM candles s
WHERE s.day<s2.day
AND s.minute=s2.minute
ORDER BY s.id DESC
LIMIT 1);
Result:
Update on candles s2 (cost=0.00..513040.75 rows=80240 width=68)
-> Seq Scan on candles s2 (cost=0.00..513040.75 rows=80240 width=68)
SubPlan 1
-> Limit (cost=0.29..6.37 rows=1 width=4)
-> Index Scan Backward using candles_pkey on candles s (cost=0.29..4784.85 rows=787 width=4)
Filter: ((day < s2.day) AND (minute = s2.minute))
How should I modify query or schema to run it in reasonable time?