-- Index the crashed-worker-recovery arm of the job lease predicate. -- -- lease/lease_kinds match: -- WHERE (state = 'pending' OR (state = 'running' AND leased_until < now())) -- crawler_jobs_ready_idx (0016) is `ON (scheduled_at) WHERE state = 'pending'`, -- so it covers only the pending arm. The `state = 'running' AND leased_until` -- arm had no usable index, so Postgres could not BitmapOr the two arms and -- degraded to a sequential scan of the ENTIRE crawler_jobs table — including all -- done/dead rows not yet reaped — on every lease poll, by every worker, -- continuously (audit H2, the headline performance finding). -- -- A partial index on leased_until over just the running rows makes the recovery -- arm index-backed. `state = 'running'` is an immutable predicate (now() stays -- in the query, not the index). The running set is tiny (in-flight jobs only), -- so the index is cheap to maintain. CREATE INDEX crawler_jobs_running_lease_idx ON crawler_jobs (leased_until) WHERE state = 'running';