perf(db): batch node lookups, fix insertNode cache, run maintenance after writes (#108)
Batch getNodesByIds to collapse N+1 reads in graph traversal, invalidate the insertNode LRU cache so INSERT OR REPLACE doesn't serve a stale row, and run incremental PRAGMA optimize + passive WAL checkpoint after bulk writes. Closes #108
This commit is contained in:
@@ -186,6 +186,36 @@ export class DatabaseConnection {
|
||||
this.db.exec('ANALYZE');
|
||||
}
|
||||
|
||||
/**
|
||||
* Lightweight, non-blocking maintenance to run after bulk writes
|
||||
* (indexAll, sync). Two operations:
|
||||
*
|
||||
* - `PRAGMA optimize` — incremental ANALYZE; SQLite only re-analyzes
|
||||
* tables whose row counts changed materially since the last
|
||||
* ANALYZE. Without it, the query planner has no statistics on the
|
||||
* freshly-bulk-loaded tables and can pick suboptimal indexes.
|
||||
*
|
||||
* - `PRAGMA wal_checkpoint(PASSIVE)` — fold pending WAL pages back
|
||||
* into the main database file so the WAL file doesn't grow
|
||||
* unboundedly between automatic checkpoints (auto-fires at 1000
|
||||
* pages by default; large indexAll runs blow past that).
|
||||
*
|
||||
* Both operations are silently swallowed on failure — they're a
|
||||
* best-effort optimization, never load-bearing for correctness.
|
||||
*/
|
||||
runMaintenance(): void {
|
||||
try {
|
||||
this.db.exec('PRAGMA optimize');
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
this.db.exec('PRAGMA wal_checkpoint(PASSIVE)');
|
||||
} catch {
|
||||
// ignore (e.g., not in WAL mode)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the database connection
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user