当前位置:首页 > 文章列表 > 数据库 > MySQL > MySQL Optimizer Trace 怎么查看索引选择原因

MySQL Optimizer Trace 怎么查看索引选择原因

来源:17golang原创 2026-09-28 17:36:41 0浏览 收藏

MySQL 明明有索引,优化器却选择了全表扫描或另一条索引,单看 EXPLAIN 往往只能看到“选了什么”,看不到“为什么这样选”。这时可以在同一个连接里开启 Optimizer Trace:执行原查询,再读取 INFORMATION_SCHEMA.OPTIMIZER_TRACE,从候选访问路径、估算行数和成本判断索引落选原因。

官方地址:https://dev.mysql.com/

要点速览
  • Optimizer Trace 只观察当前会话,开启、执行、读取、关闭必须使用同一个连接。
  • 先看候选索引是否可用,再比较估算行数与成本,最后确认 chosen 或 cause。
  • Trace 是诊断依据,不等于强制改索引;统计信息、数据分布和 SQL 写法仍要一起核对。

先用 EXPLAIN 固定要分析的查询与索引候选

建议先把线上慢 SQL 脱敏后放到测试或只读环境,用 EXPLAIN 看当前计划。下面的例子假设订单表上有 idx_status_created_at,查询希望按状态和创建时间过滤:

-- 先记录当前计划,确认实际查询与索引候选
EXPLAIN
SELECT id, user_id, created_at
FROM orders
WHERE status = 'paid'
  AND created_at >= '2026-09-01'
ORDER BY created_at DESC
LIMIT 50;

如果 key 为空,或者 key 不是预期索引,先记下 possible_keys、rows、filtered 和 Extra。Trace 的任务不是替代 EXPLAIN,而是把优化器在计划生成阶段比较过的候选展开。

MySQL Optimizer Trace 当前会话从 EXPLAIN 到执行查询再到 OPTIMIZER_TRACE 的流程说明图
图1:MySQL Optimizer Trace 会话流程说明图,展示开启、执行、读取和关闭的边界。

在当前会话开启 optimizer_trace 并执行原语句

不要只执行开启语句后换到另一个连接。官方流程要求在当前会话执行被追踪的语句;连接池场景尤其容易因为连接切换而读不到预期结果。

-- 只在当前诊断连接打开追踪,并给较大的 Trace 留出空间
SET optimizer_trace = 'enabled=on';
SET optimizer_trace_max_mem_size = 1000000;

-- 在同一连接执行要分析的原查询
SELECT id, user_id, created_at
FROM orders
WHERE status = 'paid'
  AND created_at >= '2026-09-01'
ORDER BY created_at DESC
LIMIT 50;

-- 读取当前会话最近的优化器记录
SELECT QUERY, TRACE, MISSING_BYTES_BEYOND_MAX_MEM_SIZE,
       INSUFFICIENT_PRIVILEGES
FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE\G

optimizer_trace_max_mem_size 过小,Trace 可能被截断;出现非零的 MISSING_BYTES_BEYOND_MAX_MEM_SIZE 时,先扩大诊断会话的上限再重跑。追踪结束后要执行:

-- 诊断完成立即关闭,避免这个连接继续积累 Trace
SET optimizer_trace = 'enabled=off';

从 OPTIMIZER_TRACE 读取候选路径与成本

TRACE 是 JSON 文本,不要从第一行直接跳到结论。先按下面的顺序搜索关键对象;不同 SQL 的节点组合会变化,但“可用性—估算—成本—选择”这条阅读路径比较稳定。

观察位置重点字段能回答什么
范围或访问路径分析index、ranges、usable候选索引是否能匹配谓词
行数估算rows、过滤比例、扫描范围优化器预计要读多少数据
成本比较cost、cost_for_plan为什么某条路径在模型中更便宜
最终决策chosen、cause哪条路径胜出、其他路径为何被淘汰

例如,看到某索引 usable: false,方向通常是谓词无法形成有效范围、类型或排序条件不匹配;看到多个索引都可用但成本不同,就要继续对照估算行数、回表代价和排序代价。不要把“用了索引”当成“更快”的证明,Trace 记录的是优化器当时掌握的统计与成本判断。

MySQL Optimizer Trace 索引选择说明图,展示候选索引经过可用性、行数估算和成本比较后确定 chosen 路径
图2:索引选择结构说明图,展示候选路径从可用性到成本比较的判断关系。

根据 cause 与 chosen 判断索引为何落选

排查时把 Trace 当成“决策链”,而不是一串必须全部读懂的 JSON。可以先定位目标索引名称,再向上找它所在的分析对象:

  1. 先查可用性:如果候选索引没有进入范围分析,检查列类型、隐式转换、函数包裹、联合索引最左列和排序方向。
  2. 再查估算:索引可用但预计行数很大,优先核对统计信息和数据分布,不要立即用 FORCE INDEX 掩盖问题。
  3. 最后看成本:如果候选被 pruned_by_cost 或类似原因淘汰,说明它参与过比较,只是模型认为另一条计划更便宜。

Trace 只能解释优化器的选择依据,不能直接证明真实执行耗时。结论最好与 EXPLAIN ANALYZE、表统计信息和实际数据分布交叉核对;生产环境先在低风险窗口或副本上复现。

关闭追踪并把结论落到统计信息与索引设计

如果确认是统计信息偏旧,更新统计信息后重新执行同一组 EXPLAIN 与 Trace;如果是索引列顺序或排序需求不匹配,再调整索引设计。若只是单条特殊查询,不要把 Trace 里的某个候选直接固化成全局规则。

一个可复用的检查清单是:同一连接、同一 SQL、Trace 未截断、候选索引确实可用、估算值与数据分布没有明显偏差、成本结论与实际执行计划相互印证。这样才能回答“为什么没选这条索引”,而不是只得到“加一个索引再试试”。

常见问题

Optimizer Trace 能读取其他连接执行过的 SQL 吗?

不能。官方说明它只追踪当前会话执行的语句,必须在同一个连接里开启、执行和读取。

Trace 为空是不是索引没有生效?

不一定。先确认是否换了连接、是否真的执行了目标语句,再检查追踪开关和读取权限。

为什么 Trace 里有索引但最终仍然全表扫描?

索引“可用”只表示进入了比较过程;如果估算行数或综合成本更高,它仍可能在最终决策中落选。

需要一直打开 optimizer_trace 吗?

不需要。它适合短时间诊断,读完结果就关闭,并保留 SQL、EXPLAIN 和关键 Trace 片段供复盘。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Redis GEOSEARCHSTORE 怎么保存附近对象结果Redis GEOSEARCHSTORE 怎么保存附近对象结果
上一篇
Redis GEOSEARCHSTORE 怎么保存附近对象结果
Go filepath.IsLocal 怎么筛除绝对路径和逃逸路径
下一篇
Go filepath.IsLocal 怎么筛除绝对路径和逃逸路径
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    253次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    298次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    271次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    251次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    57次使用