diff --git a/conf/configuration.go b/conf/configuration.go index 58ba2c5f9..498a28955 100644 --- a/conf/configuration.go +++ b/conf/configuration.go @@ -132,6 +132,7 @@ type configOptions struct { DevEnablePluginsInsights bool DevPluginCompilationTimeout time.Duration DevExternalArtistFetchMultiplier float64 + DevOptimizeDB bool } type scannerOptions struct { @@ -438,7 +439,7 @@ func validatePurgeMissingOption() error { } } if !valid { - err := fmt.Errorf("Invalid Scanner.PurgeMissing value: '%s'. Must be one of: %v", Server.Scanner.PurgeMissing, allowedValues) + err := fmt.Errorf("invalid Scanner.PurgeMissing value: '%s'. Must be one of: %v", Server.Scanner.PurgeMissing, allowedValues) log.Error(err.Error()) Server.Scanner.PurgeMissing = consts.PurgeMissingNever return err @@ -630,6 +631,7 @@ func setViperDefaults() { viper.SetDefault("devenablepluginsinsights", true) viper.SetDefault("devplugincompilationtimeout", time.Minute) viper.SetDefault("devexternalartistfetchmultiplier", 1.5) + viper.SetDefault("devoptimizedb", true) } func init() { diff --git a/db/db.go b/db/db.go index cb1ebd9e3..71bc082b2 100644 --- a/db/db.go +++ b/db/db.go @@ -45,10 +45,12 @@ func Db() *sql.DB { if err != nil { log.Fatal("Error opening database", err) } - _, err = db.Exec("PRAGMA optimize=0x10002") - if err != nil { - log.Error("Error applying PRAGMA optimize", err) - return nil + if conf.Server.DevOptimizeDB { + _, err = db.Exec("PRAGMA optimize=0x10002") + if err != nil { + log.Error("Error applying PRAGMA optimize", err) + return nil + } } return db }) @@ -99,7 +101,7 @@ func Init(ctx context.Context) func() { log.Fatal(ctx, "Failed to apply new migrations", err) } - if hasSchemaChanges { + if hasSchemaChanges && conf.Server.DevOptimizeDB { log.Debug(ctx, "Applying PRAGMA optimize after schema changes") _, err = db.ExecContext(ctx, "PRAGMA optimize") if err != nil { @@ -114,6 +116,9 @@ func Init(ctx context.Context) func() { // Optimize runs PRAGMA optimize on each connection in the pool func Optimize(ctx context.Context) { + if !conf.Server.DevOptimizeDB { + return + } numConns := Db().Stats().OpenConnections if numConns == 0 { log.Debug(ctx, "No open connections to optimize") diff --git a/db/migrations/migration.go b/db/migrations/migration.go index 8d8f8a91e..fde6f5817 100644 --- a/db/migrations/migration.go +++ b/db/migrations/migration.go @@ -7,6 +7,7 @@ import ( "strings" "sync" + "github.com/navidrome/navidrome/conf" "github.com/navidrome/navidrome/consts" ) @@ -21,11 +22,13 @@ func notice(tx *sql.Tx, msg string) { // Call this in migrations that requires a full rescan func forceFullRescan(tx *sql.Tx) error { // If a full scan is required, most probably the query optimizer is outdated, so we run `analyze`. - _, err := tx.Exec(`ANALYZE;`) - if err != nil { - return err + if conf.Server.DevOptimizeDB { + _, err := tx.Exec(`ANALYZE;`) + if err != nil { + return err + } } - _, err = tx.Exec(fmt.Sprintf(` + _, err := tx.Exec(fmt.Sprintf(` INSERT OR REPLACE into property (id, value) values ('%s', '1'); `, consts.FullScanAfterMigrationFlagKey)) return err diff --git a/persistence/library_repository.go b/persistence/library_repository.go index 5621e1719..9349f3c4c 100644 --- a/persistence/library_repository.go +++ b/persistence/library_repository.go @@ -179,7 +179,9 @@ func (r *libraryRepository) ScanEnd(id int) error { // https://www.sqlite.org/pragma.html#pragma_optimize // Use mask 0x10000 to check table sizes without running ANALYZE // Running ANALYZE can cause query planner issues with expression-based collation indexes - _, err = r.executeSQL(Expr("PRAGMA optimize=0x10000;")) + if conf.Server.DevOptimizeDB { + _, err = r.executeSQL(Expr("PRAGMA optimize=0x10000;")) + } return err }