The merger's neighbour query matched "end_id = ? OR start_id = ?", which no index serves: it read every range of the group per file, 5.5 s a round and most of Postgres's time in an end-to-end run. Now the range holding the article before and after, by (group_id, start_id): 0.08 ms. The prefetcher's leased and started ranges (every 2 s) get partial indexes: 15-25 ms -> <0.1 ms with 145k planned ranges. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
19 lines
749 B
TypeScript
19 lines
749 B
TypeScript
import { BaseSchema } from '@adonisjs/lucid/schema'
|
||
|
||
/**
|
||
* The prefetcher's ranges every 2 s (REBUILD.md, prefetch): the leased ones
|
||
* and the planned ones it started spooling. Without these it read all
|
||
* ranges each time (~15–25 ms with 145k planned; LOG.md 2026-10-09).
|
||
*/
|
||
export default class extends BaseSchema {
|
||
async up() {
|
||
this.schema.raw(`CREATE INDEX IF NOT EXISTS ranges_leased_idx ON ranges (leased_at) WHERE status = 'leased'`)
|
||
this.schema.raw(`CREATE INDEX IF NOT EXISTS ranges_spooling_idx ON ranges (priority, id) WHERE status = 'planned' AND spooled_chunks > 0`)
|
||
}
|
||
|
||
async down() {
|
||
this.schema.raw(`DROP INDEX IF EXISTS ranges_spooling_idx`)
|
||
this.schema.raw(`DROP INDEX IF EXISTS ranges_leased_idx`)
|
||
}
|
||
}
|