优化索引

This commit is contained in:
2025-09-24 16:48:41 +08:00
parent 47b8c5bc65
commit 2070653f2f
3 changed files with 30 additions and 13 deletions

View File

@@ -120,16 +120,9 @@ func (ps *PostgresStorage) Migrate(models ...interface{}) error {
ps.logger.Info("数据库表结构迁移完成")
// -- 处理gorm做不到的初始化逻辑 --
// 创建GIN索引(用于优化JSONB查询)
ps.logger.Info("正在为 sensor_data 表的 data 字段创建 GIN 索引")
// 使用 IF NOT EXISTS 保证幂等性
// 如果索引已存在,此命令不会报错
ginIndexSQL := "CREATE INDEX IF NOT EXISTS idx_sensor_data_data_gin ON sensor_data USING GIN (data);"
if err := ps.db.Exec(ginIndexSQL).Error; err != nil {
ps.logger.Errorw("为 sensor_data 的 data 字段创建 GIN 索引失败", "error", err)
return fmt.Errorf("为 sensor_data 的 data 字段创建 GIN 索引失败: %w", err)
if err := ps.creatingIndex(); err != nil {
return err
}
ps.logger.Info("成功为 sensor_data 的 data 字段创建 GIN 索引 (或已存在)")
// 如果是 TimescaleDB, 则将 sensor_data 转换为 hypertable
if ps.isTimescaleDB {
@@ -146,3 +139,27 @@ func (ps *PostgresStorage) Migrate(models ...interface{}) error {
}
return nil
}
// creatingIndex 用于创建gorm无法处理的索引, 如gin索引
func (ps *PostgresStorage) creatingIndex() error {
// 创建GIN索引(用于优化JSONB查询)
ps.logger.Info("正在为 sensor_data 表的 data 字段创建 GIN 索引")
// 使用 IF NOT EXISTS 保证幂等性
// 如果索引已存在,此命令不会报错
ginIndexSQL := "CREATE INDEX IF NOT EXISTS idx_sensor_data_data_gin ON sensor_data USING GIN (data);"
if err := ps.db.Exec(ginIndexSQL).Error; err != nil {
ps.logger.Errorw("为 sensor_data 的 data 字段创建 GIN 索引失败", "error", err)
return fmt.Errorf("为 sensor_data 的 data 字段创建 GIN 索引失败: %w", err)
}
ps.logger.Info("成功为 sensor_data 的 data 字段创建 GIN 索引 (或已存在)")
// 为 tasks.parameters 创建 GIN 索引
ps.logger.Info("正在为 tasks 表的 parameters 字段创建 GIN 索引")
taskGinIndexSQL := "CREATE INDEX IF NOT EXISTS idx_tasks_parameters_gin ON tasks USING GIN (parameters);"
if err := ps.db.Exec(taskGinIndexSQL).Error; err != nil {
ps.logger.Errorw("为 tasks 的 parameters 字段创建 GIN 索引失败", "error", err)
return fmt.Errorf("为 tasks 的 parameters 字段创建 GIN 索引失败: %w", err)
}
ps.logger.Info("成功为 tasks 的 parameters 字段创建 GIN 索引 (或已存在)")
return nil
}

View File

@@ -53,8 +53,8 @@ type Plan struct {
Name string `gorm:"not null" json:"name"`
Description string `json:"description"`
ExecutionType PlanExecutionType `gorm:"not null" json:"execution_type"`
Status PlanStatus `gorm:"default:0" json:"status"` // 计划是否被启动
ExecutionType PlanExecutionType `gorm:"not null;index" json:"execution_type"`
Status PlanStatus `gorm:"default:0;index" json:"status"` // 计划是否被启动
ExecuteNum uint `gorm:"default:0" json:"execute_num"` // 计划预期执行次数
ExecuteCount uint `gorm:"default:0" json:"execute_count"` // 执行计数器

View File

@@ -21,7 +21,7 @@ type PendingTask struct {
Task *Task `gorm:"foreignKey:TaskID"`
ExecuteAt time.Time `gorm:"index"` // 任务执行时间
TaskExecutionLogID uint `gorm:"unique;not null"` // 对应的执行历史记录ID
TaskExecutionLogID uint `gorm:"unique;not null;index"` // 对应的执行历史记录ID
// 通过 TaskExecutionLogID 关联到唯一的 TaskExecutionLog 记录
// ON DELETE CASCADE 确保如果日志被删除,这个待办任务也会被自动清理