From c8e4fa7a95bf63be38cdc119014b062b9be4747c Mon Sep 17 00:00:00 2001 From: Dorian Date: Mon, 9 Mar 2026 00:02:47 +0000 Subject: [PATCH] perf: SQLite WAL mode and indexes Add PRAGMA synchronous=NORMAL, temp_store=MEMORY, mmap_size=256MB for better write throughput and query performance. Create 11 indexes on commonly queried columns (fights.status, fights.created_at, bots.elo, rounds.fight_id, payments, tournament_matches). Run PRAGMA optimize on startup for query planner statistics. Co-Authored-By: Claude Opus 4.6 --- server/src/db/index.ts | 3 +++ server/src/db/startup.ts | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/server/src/db/index.ts b/server/src/db/index.ts index 3276c64..75f77a6 100644 --- a/server/src/db/index.ts +++ b/server/src/db/index.ts @@ -12,6 +12,9 @@ mkdirSync(dirname(dbPath), { recursive: true }) const sqlite = new Database(dbPath) sqlite.pragma('journal_mode = WAL') sqlite.pragma('foreign_keys = ON') +sqlite.pragma('synchronous = NORMAL') +sqlite.pragma('temp_store = MEMORY') +sqlite.pragma('mmap_size = 268435456') // 256MB memory-mapped I/O export const db = drizzle(sqlite, { schema }) export { schema, sqlite } diff --git a/server/src/db/startup.ts b/server/src/db/startup.ts index b012cd0..a5cbed9 100644 --- a/server/src/db/startup.ts +++ b/server/src/db/startup.ts @@ -160,5 +160,23 @@ export function runMigrations() { sqlite.exec("UPDATE bots SET bot_type = 'classic' WHERE webhook_url LIKE 'http://classic.local%' AND bot_type = 'regular'") } catch { /* ok */ } + // Indexes for common query patterns + sqlite.exec(` + CREATE INDEX IF NOT EXISTS idx_fights_status ON fights(status); + CREATE INDEX IF NOT EXISTS idx_fights_created ON fights(created_at); + CREATE INDEX IF NOT EXISTS idx_fights_bot_a ON fights(bot_a_id); + CREATE INDEX IF NOT EXISTS idx_fights_bot_b ON fights(bot_b_id); + CREATE INDEX IF NOT EXISTS idx_bots_elo ON bots(elo_rating); + CREATE INDEX IF NOT EXISTS idx_bots_tier ON bots(tier); + CREATE INDEX IF NOT EXISTS idx_bots_active ON bots(is_active); + CREATE INDEX IF NOT EXISTS idx_rounds_fight ON rounds(fight_id); + CREATE INDEX IF NOT EXISTS idx_payments_status ON payments(status); + CREATE INDEX IF NOT EXISTS idx_payments_bot ON payments(bot_id); + CREATE INDEX IF NOT EXISTS idx_tournament_matches_tournament ON tournament_matches(tournament_id); + `) + + // Run PRAGMA optimize on startup for query planner stats + sqlite.pragma('optimize') + logger.info('db', 'database migrated') }