소스 검색

perf(db): add an index on settings.key (#5359)

getSetting (WHERE key=?) runs on nearly every subscription request and job
tick and had no index, so each lookup full-scans the settings table past the
large xrayTemplateConfig blob. Add an index on settings.key; AutoMigrate
creates it on existing DBs too. Includes a HasIndex test.
n0ctal 21 시간 전
부모
커밋
3cf3fddf12
2개의 변경된 파일31개의 추가작업 그리고 1개의 파일을 삭제
  1. 1 1
      internal/database/model/model.go
  2. 30 0
      internal/database/settings_index_test.go

+ 1 - 1
internal/database/model/model.go

@@ -486,7 +486,7 @@ func HealMtprotoSecret(settings string) (string, bool) {
 // Setting stores key-value configuration settings for the 3x-ui panel.
 type Setting struct {
 	Id    int    `json:"id" form:"id" gorm:"primaryKey;autoIncrement"`
-	Key   string `json:"key" form:"key"`
+	Key   string `json:"key" form:"key" gorm:"index:idx_settings_key"`
 	Value string `json:"value" form:"value"`
 }
 

+ 30 - 0
internal/database/settings_index_test.go

@@ -0,0 +1,30 @@
+package database
+
+import (
+	"testing"
+
+	"gorm.io/driver/sqlite"
+	"gorm.io/gorm"
+	"gorm.io/gorm/logger"
+
+	"github.com/mhsanaei/3x-ui/v3/internal/database/model"
+)
+
+// settings.key is read on nearly every request and job tick (getSetting
+// WHERE key=?); AutoMigrate must create the index so those lookups don't
+// full-scan the settings table past the large xrayTemplateConfig blob. gorm
+// creates missing indexes on migrate, so this also covers existing DBs.
+func TestAutoMigrateCreatesSettingsKeyIndex(t *testing.T) {
+	db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{
+		Logger: logger.Default.LogMode(logger.Silent),
+	})
+	if err != nil {
+		t.Fatalf("open sqlite: %v", err)
+	}
+	if err := db.AutoMigrate(&model.Setting{}); err != nil {
+		t.Fatalf("automigrate: %v", err)
+	}
+	if !db.Migrator().HasIndex(&model.Setting{}, "idx_settings_key") {
+		t.Errorf("expected idx_settings_key to exist after AutoMigrate")
+	}
+}