Would be glad if you could help me out:
Got a query that is supposed to take some task from the database (Postgres) partitioned table (partitioned by execute_ts) and take them to work thread-safely (with several workers in the service taking the tasks of the DB concurrently)
UPDATE tasks
SET status = 'IN_WORK'
WHERE execute_ts BETWEEN (now() - INTERVAL '2 day') AND now()
AND id IN (
SELECT id
FROM tasks
WHERE status IN ('INITIAL', 'TO_BE_RETRIED')
AND execute_ts BETWEEN (now() - INTERVAL '2 day') AND now()
LIMIT 1000
FOR UPDATE SKIP LOCKED
)
RETURNING *;
Is there a way to avoid repeating execute_ts BETWEEN (now() - INTERVAL '2 day') AND now()
conditions, because otherwise it traverses all partitions.
2
Answers
Try with
CTE
, like the followingThe tuple identifier
ctid
is a good way to achieve an efficient self-join. However, according to this question on DBA.SE one needs to combine it with thetableoid
to work correctly in partitioned tables, and one should use a CTE instead of a subquery: