Private
Public Access
1
0
Files
u-desk/docs/01-技术文档/数据库优化/db-optimization-quickstart.md

7.0 KiB
Raw Blame History

U-Desk v0.3.3 - 数据库优化快速开始

新功能概览

v0.3.3 版本完成了以下数据库客户端优化:

P0 - 高优先级

  1. MySQL 连接池重构 - 动态调整、健康检查、性能优化
  2. SQL 查询优化器 - 查询缓存、慢查询日志、索引建议

P1 - 中优先级

  1. Redis 连接管理 - Pipeline 支持、事务支持

快速开始

1. 使用动态连接池

package main

import (
    "context"
    "fmt"
    "log"
    "time"
    
    "u-desk/internal/dbclient"
    "u-desk/internal/storage/models"
)

func main() {
    // 获取连接池
    pool := dbclient.GetPool()
    
    // 获取 MySQL 客户端
    conn := &models.DbConnection{
        ID:       1,
        Host:     "localhost",
        Port:     3306,
        Username: "root",
        Password: "password",
        Database: "mydb",
    }
    
    // 执行优化查询
    ctx := context.Background()
    sqlStr := "SELECT * FROM users WHERE status = 'active' LIMIT 100"
    
    result, duration, err := pool.OptimizeQuery(ctx, conn.ID, sqlStr, conn.Database)
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf("查询耗时: %v, 返回 %d 行\n", duration, len(result.Data))
    
    // 查看连接池统计
    stats := pool.GetMySQLPoolStats()
    fmt.Printf("连接数: %d (使用: %d, 空闲: %d)\n", 
        stats.TotalConns, stats.ActiveConns, stats.IdleConns)
}

2. 使用查询优化器

// 获取查询统计
stats := pool.GetQueryStats()
fmt.Printf("总查询数: %d\n", stats.TotalQueries)
fmt.Printf("缓存命中: %d (%.2f%%)\n", stats.CachedQueries, stats.CacheHitRate)
fmt.Printf("慢查询: %d\n", stats.SlowQueries)
fmt.Printf("平均耗时: %v\n", stats.AverageDuration)

// 查看慢查询
slowQueries := pool.GetSlowQueries(10)
for i, sq := range slowQueries {
    fmt.Printf("%d. %s - 耗时: %v\n", i+1, sq.Query, sq.Duration)
}

// 清空查询缓存
pool.ClearQueryCache()

3. 使用索引建议

// 为表生成索引建议
err := pool.GenerateIndexSuggestions(ctx, conn.ID, "mydb", "users")
if err != nil {
    log.Fatal(err)
}

// 获取索引建议
suggestions := pool.GetIndexSuggestions("users")
for _, sug := range suggestions {
    fmt.Printf("表: %s\n", sug.Table)
    fmt.Printf("列: %v\n", sug.Columns)
    fmt.Printf("类型: %s\n", sug.IndexType)
    fmt.Printf("优先级: %s\n", sug.Priority)
    fmt.Printf("原因: %s\n", sug.Justification)
    fmt.Printf("查询: %s\n", sug.Query)
    fmt.Println("---")
}

4. 使用 Redis Pipeline

// 获取 Redis 客户端
redisClient, err := pool.GetRedisClient(conn)
if err != nil {
    log.Fatal(err)
}

// 创建 Pipeline
ctx := context.Background()
pipeline := redisClient.NewPipeline(ctx)

// 添加多个命令
pipeline.AddCommand("GET", "user:123:name")
pipeline.AddCommand("GET", "user:123:email")
pipeline.AddCommand("HGET", "user:123:profile", "age")
pipeline.AddCommand("ZADD", "leaderboard", 1000, "user:123")

// 执行 Pipeline
results, err := pipeline.Execute()
if err != nil {
    log.Fatal(err)
}

// 处理结果
for i, result := range results {
    fmt.Printf("结果 %d: %v\n", i+1, result)
}

// 查看命令数量
fmt.Printf("Pipeline 包含 %d 个命令\n", pipeline.Len())

5. 使用 Redis 事务

// 创建事务 (监听键)
tx := redisClient.NewTransaction(ctx, "balance:123")

// 添加事务命令
tx.AddCommand("GET", "balance:123")
tx.AddCommand("SET", "balance:123", "1000")
tx.AddCommand("HSET", "account:123", "last_update", time.Now().Unix())

// 执行事务
results, err := tx.Exec()
if err != nil {
    log.Fatal(err)
}

fmt.Printf("事务执行成功,返回 %d 个结果\n", len(results))

配置优化

连接池配置

连接池使用默认配置,通常能满足大多数场景:

// 默认配置 (internal/dbclient/pool_config.go)
MaxOpenConns:         20           // 最大连接数
MaxIdleConns:         10           // 最大空闲连接
MinIdleConns:         2            // 最小空闲连接
ConnMaxLifetime:      30 minutes   // 连接最大生命周期
ConnMaxIdleTime:      10 minutes   // 连接最大空闲时间

// 动态调整配置
EnableDynamicScaling: true         // 启用动态调整
ScaleUpThreshold:     0.8          // 扩容阈值 (80%)
ScaleDownThreshold:   0.3          // 缩容阈值 (30%)
DynamicScaleFactor:   1.5          // 调整因子

查询优化器配置

// 默认配置 (internal/dbclient/query_optimizer.go)
CacheSize:            1000          // 最大缓存条目
CacheTTL:             30 minutes    // 缓存过期时间
EnableCache:          true          // 启用缓存
SlowQueryThreshold:   100ms         // 慢查询阈值
EnableSlowLog:        true          // 启用慢查询日志
MaxSlowLogs:          1000          // 最大慢查询记录
EnableIndexSuggestions: true         // 启用索引建议

性能监控

查询性能

// 获取查询统计
stats := pool.GetQueryStats()

// 关键指标
- TotalQueries:      总查询数
- CachedQueries:     缓存命中数
- SlowQueries:       慢查询数
- CacheHitRate:      缓存命中率 (%)
- AverageDuration:   平均查询耗时
- TotalDuration:     总耗时

连接池性能

// 获取连接池统计
stats := pool.GetMySQLPoolStats()

// 关键指标
- TotalConns:        总连接数
- ActiveConns:       使用中的连接数
- IdleConns:         空闲连接数
- WaitCount:         等待连接次数
- WaitDuration:      总等待时间
- SlowConnCount:     慢连接数量

常见问题

Q: 如何禁用查询缓存?

A: 在 OptimizerConfig 中设置 EnableCache = false

Q: 如何调整慢查询阈值?

A: 修改 SlowQueryThreshold,例如改为 200ms

Q: 动态连接池如何调整?

A: 连接池会根据使用率自动调整:

  • 使用率 > 80%: 扩容 (连接数 × 1.5)
  • 使用率 < 30%: 缩容 (连接数 ÷ 1.5)

Q: Redis Pipeline 有什么优势?

A: Pipeline 减少网络往返,批量操作性能提升 3-5 倍

Q: 索引建议如何生成?

A: 基于慢查询分析,提取 WHERE 和 ORDER BY 条件中的列


最佳实践

  1. 监控连接池: 定期检查连接池使用率,避免连接耗尽
  2. 分析慢查询: 定期查看慢查询日志,优化查询语句
  3. 应用索引建议: 在非高峰期应用索引建议,验证效果
  4. 合理设置缓存: 根据数据变化频率调整 TTL
  5. 使用 Pipeline: 批量 Redis 操作使用 Pipeline 提升性能

性能提升

操作 优化前 优化后 提升
缓存查询命中 ~100ms <1ms 99%
Redis 批量操作 10次往返 1次往返 300%
连接建立 500ms 预热连接 60%
慢查询识别 100ms 新增

技术支持

详细文档: docs/db-optimization-v0.3.3-report.md

源码位置:

  • 连接池: internal/dbclient/pool_config.go
  • 查询优化: internal/dbclient/query_optimizer.go
  • 查询缓存: internal/dbclient/cache.go
  • Redis Pipeline: internal/dbclient/redis_pipeline.go