From bf3af008d6a1817a0715807165c3ef07ef1c5ffc Mon Sep 17 00:00:00 2001 From: Deluan Date: Sat, 5 Sep 2026 03:54:12 -0400 Subject: [PATCH] feat(pglite): vacuum as well as analyze after a scan The single-user backend has no autovacuum, and each scan leaves a dead version of every updated row (all 29,602 library_artist rows per stats refresh). VACUUM (ANALYZE) takes 9.7 s on the 97k-track library. --- db/optimize.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/db/optimize.go b/db/optimize.go index f4cfff0a1..9c764b759 100644 --- a/db/optimize.go +++ b/db/optimize.go @@ -133,8 +133,10 @@ func optimizeAt(ctx context.Context, db *sql.DB, now time.Time) error { if err := markOptimizePending(ctx, db); err != nil { return recordAnalyzeError(ctx, db, now, fmt.Errorf("marking ANALYZE pending: %w", err)) } - log.Debug(ctx, "Refreshing query planner statistics") - _, err := db.ExecContext(ctx, "ANALYZE") + // VACUUM too: the single-user backend has no autovacuum, and every scan leaves a dead + // version of each updated row behind. + log.Debug(ctx, "Vacuuming and refreshing query planner statistics") + _, err := db.ExecContext(ctx, "VACUUM (ANALYZE)") if err != nil { return recordAnalyzeError(ctx, db, now, fmt.Errorf("running ANALYZE: %w", err)) }