From dd3e5427f482630fc598082e5af122b6b3c0b2d7 Mon Sep 17 00:00:00 2001 From: Jan Eitzinger Date: Fri, 13 Mar 2026 13:12:54 +0100 Subject: [PATCH] Add covering indexes for status/dashboard queries (migration 13) Adds composite covering indexes on (cluster, job_state, , ...) for user, project, and subcluster groupings to enable index-only scans for status views. Drops subsumed 3-column indexes. Co-Authored-By: Claude Opus 4.6 Entire-Checkpoint: 3d8def28e96e --- internal/repository/migration.go | 3 ++- .../13_status-covering-indexes.down.sql | 12 ++++++++++++ .../sqlite3/13_status-covering-indexes.up.sql | 18 ++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 internal/repository/migrations/sqlite3/13_status-covering-indexes.down.sql create mode 100644 internal/repository/migrations/sqlite3/13_status-covering-indexes.up.sql diff --git a/internal/repository/migration.go b/internal/repository/migration.go index c05ca42f..5a530d2d 100644 --- a/internal/repository/migration.go +++ b/internal/repository/migration.go @@ -21,12 +21,13 @@ import ( // is added to internal/repository/migrations/sqlite3/. // // Version history: +// - Version 13: Add covering indexes for status/dashboard queries (cluster, job_state, ...) // - Version 12: Add covering index for stats queries (cluster, start_time, hpc_user, ...) // - Version 11: Optimize job table indexes (reduce from ~78 to 48) // - Version 10: Node table // // Migration files are embedded at build time from the migrations directory. -const Version uint = 12 +const Version uint = 13 //go:embed migrations/* var migrationFiles embed.FS diff --git a/internal/repository/migrations/sqlite3/13_status-covering-indexes.down.sql b/internal/repository/migrations/sqlite3/13_status-covering-indexes.down.sql new file mode 100644 index 00000000..a81f2179 --- /dev/null +++ b/internal/repository/migrations/sqlite3/13_status-covering-indexes.down.sql @@ -0,0 +1,12 @@ +-- Reverse migration 13: Remove covering status indexes, restore 3-col indexes + +DROP INDEX IF EXISTS jobs_cluster_jobstate_user_stats; +DROP INDEX IF EXISTS jobs_cluster_jobstate_project_stats; +DROP INDEX IF EXISTS jobs_cluster_jobstate_subcluster_stats; + +-- Restore the original 3-col indexes +CREATE INDEX IF NOT EXISTS jobs_cluster_jobstate_user + ON job (cluster, job_state, hpc_user); + +CREATE INDEX IF NOT EXISTS jobs_cluster_jobstate_project + ON job (cluster, job_state, project); diff --git a/internal/repository/migrations/sqlite3/13_status-covering-indexes.up.sql b/internal/repository/migrations/sqlite3/13_status-covering-indexes.up.sql new file mode 100644 index 00000000..24189527 --- /dev/null +++ b/internal/repository/migrations/sqlite3/13_status-covering-indexes.up.sql @@ -0,0 +1,18 @@ +-- Migration 13: Add covering indexes for status/dashboard queries +-- Column order: cluster (equality), job_state (equality), grouping col, then aggregated columns +-- These indexes allow the status views to be served entirely from index scans. + +CREATE INDEX IF NOT EXISTS jobs_cluster_jobstate_user_stats + ON job (cluster, job_state, hpc_user, duration, start_time, num_nodes, num_hwthreads, num_acc); + +CREATE INDEX IF NOT EXISTS jobs_cluster_jobstate_project_stats + ON job (cluster, job_state, project, duration, start_time, num_nodes, num_hwthreads, num_acc); + +CREATE INDEX IF NOT EXISTS jobs_cluster_jobstate_subcluster_stats + ON job (cluster, job_state, subcluster, duration, start_time, num_nodes, num_hwthreads, num_acc); + +-- Drop 3-col indexes that are now subsumed by the covering indexes above +DROP INDEX IF EXISTS jobs_cluster_jobstate_user; +DROP INDEX IF EXISTS jobs_cluster_jobstate_project; + +PRAGMA optimize;