Procházet zdrojové kódy

perf(db): index group_name and client_traffics hot columns (#5268)

* perf(db): index group_name and client_traffics hot columns

* fix

---------

Co-authored-by: Sanaei <[email protected]>
n0ctal před 1 dnem
rodič
revize
2188830612

+ 40 - 0
internal/database/index_tags_test.go

@@ -0,0 +1,40 @@
+package database
+
+import (
+	"testing"
+
+	"gorm.io/driver/sqlite"
+	"gorm.io/gorm"
+	"gorm.io/gorm/logger"
+
+	"github.com/mhsanaei/3x-ui/v3/internal/database/model"
+	"github.com/mhsanaei/3x-ui/v3/internal/xray"
+)
+
+// AutoMigrate must create the hot-path indexes added for client group filters
+// and client_traffics inbound lookups. gorm creates missing indexes on migrate,
+// so this also protects existing DBs after upgrade.
+func TestAutoMigrateCreatesHotPathIndexes(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.ClientRecord{}, &xray.ClientTraffic{}); err != nil {
+		t.Fatalf("automigrate: %v", err)
+	}
+
+	cases := []struct {
+		model any
+		index string
+	}{
+		{&model.ClientRecord{}, "idx_client_record_group"},
+		{&xray.ClientTraffic{}, "idx_client_traffics_inbound"},
+	}
+	for _, c := range cases {
+		if !db.Migrator().HasIndex(c.model, c.index) {
+			t.Errorf("expected index %q to exist after AutoMigrate", c.index)
+		}
+	}
+}

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

@@ -571,7 +571,7 @@ type ClientRecord struct {
 	ExpiryTime int64  `json:"expiryTime" gorm:"column:expiry_time"`
 	Enable     bool   `json:"enable" gorm:"default:true"`
 	TgID       int64  `json:"tgId" gorm:"column:tg_id"`
-	Group      string `json:"group" gorm:"column:group_name;default:''"`
+	Group      string `json:"group" gorm:"column:group_name;default:'';index:idx_client_record_group"`
 	Comment    string `json:"comment"`
 	Reset      int    `json:"reset" gorm:"default:0"`
 	CreatedAt  int64  `json:"createdAt" gorm:"autoCreateTime:milli"`

+ 1 - 1
internal/xray/client_traffic.go

@@ -4,7 +4,7 @@ package xray
 // It tracks upload/download usage, expiry times, and online status for inbound clients.
 type ClientTraffic struct {
 	Id         int    `json:"id" form:"id" gorm:"primaryKey;autoIncrement" example:"14825"`
-	InboundId  int    `json:"inboundId" form:"inboundId" example:"1"`
+	InboundId  int    `json:"inboundId" form:"inboundId" gorm:"index:idx_client_traffics_inbound" example:"1"`
 	Enable     bool   `json:"enable" form:"enable" example:"true"`
 	Email      string `json:"email" form:"email" gorm:"unique" example:"user1"`
 	UUID       string `json:"uuid" form:"uuid" gorm:"-" example:"e18c9a96-71bf-48d4-933f-8b9a46d4290c"`