必须在当前会话设置optimizer_trace="enabled=on"、end_markers_in_json=on、optimizer_trace_max_mem_size=4194304,否则trace字段易因内存不足或无结构标记导致关键内容(如potential_range_indices)缺失或不可读。

怎么开启optimizer_trace并避免信息被截断
必须在当前会话里设对三个关键参数,否则看到的TRACE字段可能缺关键内容。最常踩的坑是optimizer_trace_max_mem_size太小——默认1MB(1048576),遇到多表JOIN或联合索引时,potential_range_indices直接被砍掉。
-
SET SESSION optimizer_trace = "enabled=on", end_markers_in_json=on;:end_markers_in_json=on不是可选,它让JSON每个阶段末尾加"/* select#1 */"这类标记,否则所有嵌套结构挤成一团,根本没法定位range_analysis -
SET SESSION optimizer_trace_max_mem_size = 4194304;:建议直接设4MB,复杂查询够用;设太大(比如16MB)没坏处,但没必要 - 别用
GLOBAL级别开启:会影响其他会话,且容易被DBA策略禁止;只用SESSION级,查完立刻关
执行SQL后怎么查到有效的trace结果
执行目标SQL后,必须立刻查INFORMATION_SCHEMA.OPTIMIZER_TRACE,中间不能夹杂任何其他语句,否则trace会被覆盖。输出里真正有用的只有TRACE字段,其他字段基本不用看。
-
SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE\G:用\G而不是;,否则JSON全挤在一行,根本没法读 -
MISSING_BYTES_BEYOND_MAX_MEM_SIZE非零就说明截断了——哪怕只差1字节,potential_range_indices也可能整个消失 -
INSUFFICIENT_PRIVILEGES为1表示权限不够,常见于低权限账号,需申请PROCESS权限 - 如果
TRACE字段为空字符串,大概率是SQL执行失败(比如语法错、表不存在),优化器根本没走到优化阶段
怎么看索引为什么没被选中
重点盯steps → join_optimization → range_analysis → potential_range_indices这个路径。这里列出所有被认真评估过的索引,每个索引带rows和cost两个数字——优化器只认cost,rows只是估算依据。
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
- 如果期望的索引根本不在
potential_range_indices数组里,说明它连候选资格都没拿到:检查是否用了函数包裹(如WHERE YEAR(create_time) = 2025)、隐式类型转换(varchar字段查数字)、或索引列上有OR条件 - 如果索引在数组里,但
cost比table_scan还高,不是索引写得不好,而是优化器算出来“走索引+回表”更贵——常见原因是统计信息过期(ANALYZE TABLE能解决)或row_evaluate_cost参数偏高 -
ranges字段显示实际生成的索引查找范围,比如["customer_id >= 12345 AND customer_id 说明走了等值查找,而<code>["order_date > '2026-01-01'"]说明范围扫描生效
为什么查完要立刻关闭trace
不关的话,后续所有SQL都会被记录,内存持续占用,且OPTIMIZER_TRACE表只保留最近一次的记录——下一条SQL一执行,上一条的trace就没了。这不是功能设计缺陷,而是明确的行为契约。
-
SET SESSION optimizer_trace = "enabled=off";:关掉就行,不用设其他参数 - 别指望自动回收:MySQL不会因为会话空闲就自动关trace,它一直开着直到你手动关或会话断开
- 如果用连接池(比如Java应用),更要小心——连接复用后,trace可能还在开,导致莫名性能抖动
真正难的不是看懂JSON结构,而是把cost数字和真实数据分布对应起来。比如trace说某个索引cost=85000,但实际表才10万行,这时候得去查SHOW INDEX确认索引列顺序、查INFORMATION_SCHEMA.STATISTICS看基数是否准确——这些细节不核对,光看trace只会更迷。










