optimizer_trace不跟踪执行期物化行为,仅记录优化器生成执行计划时的决策过程,如索引选择、连接顺序、子查询改写及成本估算等;物化属于执行器阶段,其意图需通过join_optimization模块中的make_tmp_tables_info、materialize标记、subquery_materialization_cost等线索识别。

Optimizer_trace 不是用来跟踪“物化路径”的——它不记录临时表创建、中间结果落盘或执行时的物化行为。它只记录优化器在 生成执行计划阶段 的思考过程,比如索引选择、连接顺序推演、条件下推、子查询改写(如 EXISTS → semi-join)、成本估算等。所谓“物化”,属于执行器(Executor)阶段的行为,optimizer_trace 无法覆盖。
真正能反映物化决策的关键阶段是 join_optimization
在 optimizer_trace 的 JSON 输出中,join_optimization 是核心模块,它会逐层展示优化器如何评估不同执行策略。其中与“是否物化”强相关的线索包括:
- make_join_plan:列出所有被考虑的 JOIN 顺序;若某表因无合适索引被排在最后,且需配合 GROUP BY 或 DISTINCT,优化器可能倾向先扫描它并缓存结果——这是物化的前置动因
- make_tmp_tables_info:明确出现该节点,说明优化器已决定为聚合、排序或去重准备内部临时表(即逻辑物化),即使最终由内存还是磁盘承载,此处已做策略判定
- attaching_conditions_to_tables 中若显示 condition 被“下推失败”或“延迟到执行期处理”,往往意味着中间结果需暂存,以便后续过滤
- 查看 rows_estimation 下各表的预估行数:若某子查询或派生表预估返回大量行(如 > tmp_table_size),优化器会在 trace 中标记 “using temporary table” 或触发 “materialize” 策略提示(MySQL 8.0.24+ 对 materialize strategy 有更显式标注)
识别物化意图的典型 JSON 片段特征
执行类似 SELECT ... FROM (SELECT ... FROM t1 WHERE ...) AS dt JOIN t2 ON ... 后,在 trace 中搜索以下关键词:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
-
"subquery_materialization_cost":表示优化器计算了将子查询结果物化的代价 -
"materialize": true或"strategy": "materialize":明确选定物化策略(常见于 MySQL 8.0.24+) -
"table": "<derived>"</derived>+"rows": N+"filtered": 100.0:派生表未做条件下推,暗示其结果会被完整物化后再参与 JOIN -
"attached_subqueries"块内若含"executed_once": true,通常对应物化后复用
配合其他工具交叉验证物化实际行为
optimizer_trace 只说“打算怎么干”,要确认“到底干没干”和“怎么干的”,需结合:
-
EXPLAIN FORMAT=JSON:看"query_block": {"table": {"name": "<materialized>"}}</materialized>或"materialized_from_subquery"字段 -
SHOW PROFILE或performance_schema.events_statements_history:查Creating tmp table、Copying to tmp table等状态 -
SELECT * FROM performance_schema.table_io_waits_summary_by_table:观察temp_*表的 I/O 活动 - 开启
optimizer_trace_features='materialization=on'(MySQL 8.0.24+)确保物化相关决策被完整记录
实操建议:让物化路径在 trace 中更清晰可见
避免默认配置导致关键信息被截断或隐藏:
- 务必设置:
SET optimizer_trace='enabled=on', end_markers_in_json=on; - 增大缓冲:
SET optimizer_trace_max_mem_size = 2000000;(复杂嵌套易超默认 1MB) - 显式启用物化追踪:
SET optimizer_trace_features='materialization=on,greedy_search=on'; - 测试语句必须真实访问数据(如
SELECT * FROM t1 WHERE id IN (SELECT id FROM t2)),避免常量表达式跳过优化流程

















