
智能体 慢查询优化实战基准数据集与评测指标如何落地阅读说明本文以慢查询分析中的典型故障链路说明排查和设计方法。文中的告警、数字与“线上”叙述如未给出来源均应视为示例条件落地前请在自己的版本、负载和资源约束下复测。处理智能体 慢查询优化实战基准数据集与评测指标如何落地时应以可复查的日志、配置差异和最小复现为依据再判断是否需要调整方案。1. Agent 建议了 12 个复合索引数据库写入性能直接崩溃下面用一个假设场景说明 慢查询分析 中应先检查哪些信号以及如何验证判断。AI Agent 治理数据库最大的隐患在于 LLM 本身缺乏全局系统的物理代价意识。模型如果仅仅围绕“如何让当前这条 SQL 跑得最快”去思考它给出的方案必然是极度贪婪的——为查询中的每一个WHERE条件、ORDER BY字段都建上独占的索引。在真实的生产数据库中索引不是免费的午餐。每一个新增的 B 树索引都意味着每次INSERT、UPDATE、DELETE操作需要同步更新物理 Page 内存并写入 Redo/Undo Log。如果 Agent 缺乏对“写放大倍率”、“索引占用空间”以及“重复前缀索引”的权衡机制看似智能的自动化调优就会变成线上数据库的“性能杀手”。单纯依靠人工审核 Agent 输出的 DDL 语句低效。应当建立一套标准化的基准测试数据集Benchmark Dataset与确定性的评估指标体系在 Agent 建议被apply到线上前进行离线沙盒校验。2. 真实生产 Slow Log 转换为 Agent 测试集时的基准构建难题要客观评测一个 DBA Agent 的能力第一步就是准备高质量的测试数据集。直接拿生产环境的 Slow Query Log 来用会面临三个硬核瓶颈第一是数据隐私红线。慢日志中通常包含了具体的 SQL 参数值如用户 ID、身份证号、手机号、支付金额。如果将包含敏感隐私的原始 SQL 直接喂给 Agent有严重的合规泄露风险。应当在数据预处理阶段使用 AST抽象语法树解析器将变量统一替换为占位符?。第二是缺乏基准运行环境。离线环境如果只有 SQL 语句而没有对应的 Table Schema 以及符合真实数据分布的数据量如 1000 万行的真实基数与倾斜度EXPLAIN得出的 Cardinality基数估算将完全失真。Agent 针对 100 行小表作出的优化决策放到 1000 万行大表上往往完全错误。第三是评测指标单一。传统的评测只看优化后的 SQL 跑得快不快这严重偏离了工程实际。应当引入涵盖“查询加速比”、“写性能衰减率”、“索引冗余度”以及“DDL 风险系数”的复合评估矩阵。3. 基于工具调用与死循环熔断的慢查询 Agent 评估防线为了让慢查询治理 Agent 真正达到生产可用标准系统应当在 Agent 工具调用链Tool Calling Chain的外围构建一层确定性的“沙盒评估与熔断防线”。防线核心逻辑如下AST 脱敏与归一化将输入的 Slow Log 解析为标准 AST 树剔除任何字面量常量生成规范的 SQL Template。Shadow DB 快速装载在隔离的 Docker 容器中加载带有真实数据分布使用 Data Generator 填充模拟数据的 Schema 结构。DDL 代价与写放大安全校验Agent 给出CREATE INDEX建议后防线会自动分析新索引与已有索引的前缀重叠度Prefix Redundancy。如果发现该索引与现有索引前缀重叠度达 80% 以上或者预估该索引会导致该表的写放大率提升 50% 以上直接中断 Agent 的执行链并抛出拒绝反馈促使 Agent 重新迭代出兼顾读写的优雅方案。4. 带 Dry-Run 校验与索引代价计算的 Agent 评估套件实现下面的 Go 代码展示了如何实现慢查询 Agent 的确定性评估防线。包含 SQL 代价计算、索引重叠度判定以及 Tool Calling 异常熔断逻辑。package evaluator import ( context errors fmt strings sync time ) var ( ErrWriteAmplificationTooHigh errors.New(ddl rejected: estimated write amplification exceeds threshold) ErrRedundantPrefixIndex errors.New(ddl rejected: proposed index is redundant with existing indexes) ErrAgentIterationLimit errors.New(agent tool calling limit reached: dead loop detected) ) // IndexProposal 代表 Agent 提出的索引优化建议 type IndexProposal struct { TableName string Columns []string IsUnique bool } // TableMeta 记录数据库表当前的物理状态 type TableMeta struct { TableName string RowCount int64 ExistingIndexes map[string][]string // IndexName - Columns } // SafetyConfig 评测套件的安全策略限制 type SafetyConfig struct { MaxWriteAmplificationFactor float64 // 最大允许写放大因子例如 1.35 MaxToolCallIterations int // Agent 最大允许工具调用轮次 } // DBAgentEvaluator 评估器引擎 type DBAgentEvaluator struct { config SafetyConfig mu sync.RWMutex } func NewDBAgentEvaluator(cfg SafetyConfig) *DBAgentEvaluator { return DBAgentEvaluator{config: cfg} } // EvaluateDDL 评估 Agent 提交的 DDL 是否满足生产确定性安全规范 func (e *DBAgentEvaluator) EvaluateDDL(meta TableMeta, proposal IndexProposal) error { e.mu.RLock() defer e.mu.RUnlock() // 1. 前缀冗余度检查判断新索引是否已被现存索引覆盖 for idxName, cols : range meta.ExistingIndexes { if isPrefixMatch(proposal.Columns, cols) { return fmt.Errorf(%w: proposed %v matches existing index %s %v, ErrRedundantPrefixIndex, proposal.Columns, idxName, cols) } } // 2. 估算写放大因子简化模型每增加一个复合索引写成本增加 15% existingIdxCount : float64(len(meta.ExistingIndexes)) newFactor : (existingIdxCount 1.0) * 0.15 1.0 oldFactor : existingIdxCount*0.15 1.0 ratio : newFactor / oldFactor if ratio e.config.MaxWriteAmplificationFactor { return fmt.Errorf(%w: factor ratio %.2f exceeds max allowed %.2f, ErrWriteAmplificationTooHigh, ratio, e.config.MaxWriteAmplificationFactor) } return nil } func isPrefixMatch(newCols, existingCols []string) bool { if len(newCols) len(existingCols) { return false } for i : range newCols { if strings.ToLower(newCols[i]) ! strings.ToLower(existingCols[i]) { return false } } return true } // AgentRunSession 监控 Agent 工具调用生命周期防止无限循环 type AgentRunSession struct { sessionID string evaluator *DBAgentEvaluator iterations int maxIter int startTime time.Time } func NewAgentRunSession(sessionID string, eval *DBAgentEvaluator) *AgentRunSession { return AgentRunSession{ sessionID: sessionID, evaluator: eval, maxIter: eval.config.MaxToolCallIterations, startTime: time.Now(), } } // StepToolCall 每次 Agent 调用工具时触发记录 func (s *AgentRunSession) StepToolCall(ctx context.Context, toolName string) error { s.iterations if s.iterations s.maxIter { return fmt.Errorf(%w: total calls %d on tool %s, ErrAgentIterationLimit, s.iterations, toolName) } return nil }5. 线上验证从乱建索引到慢 SQL 自动治理通过率 94%引入这套基于基准数据集与确定性沙盒防线的 DBA Agent 评估体系后慢 SQL 自动治理的安全性得到了质的变化。评测集包含了来自核心交易、履约和用户中心的 500 条真实 Slow Query。在没有沙盒防线前原始 Agent 倾向于生成大量的单列和未经验证地复合索引虽然慢 SQL 解决率达到了 98%但导致数据库整体写入吞吐下降了 40%。开启 Dry-Run 校验与写放大安全拦截后 Agent 被迫在约束下重新规划索引策略。结果表明Agent 自动学会了“利用既有索引进行列追加Extend Index”以及“前缀合并”的高阶技巧。慢 SQL 治理的综合上线通过率达到了 94%且线上数据库的写性能衰减被严格控制在 3% 的微小范围内。小结把结论留给可复现的结果