讲师中心 微信公众号
AI工具推荐 视频效率加速

MySQL查询优化器中代价模型是如何工作的_解析server与engine层成本

阿瑶酱_3085

阿瑶酱_3085

发布时间:2026-05-19 19:53:21

|

529人浏览过

|

来源于php中文网

原创

MySQL代价模型由mysql.server_cost和mysql.engine_cost两张可配置系统表驱动,优化器据此结合统计信息动态计算执行计划成本;修改表后需执行FLUSH OPTIMIZER_COSTS生效。

mysql查询优化器中代价模型是如何工作的_解析server与engine层成本

MySQL代价模型依赖两个系统表:server_cost 和 engine_cost

代价模型不是硬编码的固定公式,而是由 mysql.server_costmysql.engine_cost 两张系统表驱动的可配置机制。优化器在生成执行计划前,会查这两张表获取基础成本常量,再结合统计信息(如 CardinalityRows)动态计算总代价。

常见错误是直接修改参数却没刷新缓存——MySQL 5.7+ 启动后会将这些值加载进内存,后续对表的 UPDATE 不会实时生效,必须执行 FLUSH OPTIMIZER_COSTS 才能重载。

  • server_cost 控制通用操作开销:比如 key_compare_cost(默认 0.05)影响索引扫描时的比较次数估值;row_evaluate_cost(默认 0.1)决定每行 WHERE 条件评估成本
  • engine_cost 按存储引擎区分:InnoDB 行有 io_block_read_cost(默认 1.0),MyISAM 则用另一套值;同一张表切换引擎后,代价估算可能突变
  • 不建议全局调低 disk_temptable_create_cost(默认 20.0)来“骗”优化器走内存临时表——若实际内存不足,仍会落盘,且 copying to tmp table on disk 状态会更频繁

为什么 ANALYZE TABLE 后执行计划突然变了

因为代价模型严重依赖统计信息,而 ANALYZE TABLE 会更新 information_schema.STATISTICS 中的 Cardinality 值和 SHOW TABLE STATUS 中的 Rows 估算。优化器用这些值预估“走索引能过滤掉多少行”,一旦 Cardinality 失真(例如字段大量重复但统计显示高区分度),就会高估索引效率,误选索引扫描而非全表扫描。

典型场景:某时间字段加了索引,但业务只写近 7 天数据,旧数据占表 95% 却长期不清理。ANALYZE TABLE 可能仍按全量分布采样,导致优化器认为该索引选择性差,放弃使用。

  • 验证方式:执行 SHOW INDEX FROM table_name 查看 Cardinality 是否合理;对比 SELECT COUNT(DISTINCT col) FROM table_name 的实际结果
  • 临时缓解:用 FORCE INDEX 绕过代价判断,但只是掩盖问题
  • 根本解法:对冷热分离明显的表,考虑分区(PARTITION BY RANGE),让 ANALYZE 在每个分区上独立统计

JOIN 顺序不是按 SQL 书写顺序决定的

优化器会穷举所有合法 JOIN 排列(n! 种),对每种组合分别估算成本:rows_before_join × io_block_read_cost + rows_after_join × row_evaluate_cost。最终选总代价最小的顺序,与你写的 FROM a JOIN b JOIN c 无关。

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载

容易被忽略的一点:如果某张表有 WHERE 条件且能大幅过滤(比如 WHERE status = 'done'),优化器大概率把它排在 JOIN 链最前面——不是因为它“重要”,而是它输出的中间结果集最小,后续连接成本自然降低。

  • 查看实际顺序:用 EXPLAIN FORMAT=TREE(8.0+)或 EXPLAINidselect_type 列推断
  • 强制指定顺序风险大:用 STRAIGHT_JOIN 会跳过代价计算,若数据分布变化(如某表突然膨胀 10 倍),性能可能断崖下跌
  • 小表驱动大表仍是经验法则,但仅当统计信息准确时成立;若小表的 Cardinality 被低估,优化器可能反向选择

临时表成本常量直接影响 GROUP BY / ORDER BY 是否走磁盘

当查询含 GROUP BYORDER BY 且无法利用索引排序时,MySQL 必须建临时表。此时优化器会对比内存临时表与磁盘临时表的总成本:memory_temptable_create_cost + N × memory_temptable_row_cost vs disk_temptable_create_cost + N × disk_temptable_row_cost。其中 N 是预估行数,来自 Rows 统计。

问题常出在 N 严重高估:比如 SELECT COUNT(*) FROM t WHERE create_time > '2026-05-01',但 create_time 索引的 Cardinality 过低,优化器以为要扫 100 万行,就倾向选磁盘临时表,哪怕实际只返回几百行。

  • 检查方式:观察 EXPLAINExtra 列是否含 Using temporary,再结合 SHOW PROFILECopying to tmp table 耗时占比
  • 调优方向:优先确保 GROUP BY 字段有高 Cardinality 索引;若不可行,再考虑调高 tmp_table_sizemax_heap_table_size,但这治标不治本
  • 注意:memory_temptable_row_cost 默认 0.1,比 row_evaluate_cost(0.1)还低——优化器天然偏好内存临时表,所以统计不准时更容易误判

代价模型本身不难理解,难的是统计信息如何影响它的输入。很多“优化器不走索引”的问题,根源不在模型算错,而在 CardinalityRows 这两个数字已经脱离实际好几个数量级了。

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

LibLibAI
LibLibAI Hot

一款AI视频创作工具,主要用于国内领先的AI创意平台,以海量模型、低门槛操作与“创作-分享-商业化”生态,让小白与专业创作者都能高效实现图文乃至视频创意表达,适合需要提升相关任务效率的用户。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

3703

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

771

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

949

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

5461

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2463

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

5460

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

7081

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

970

2024.04.29

Vibeknow在线使用入口合集
Vibeknow在线使用入口合集

本专题汇总了Vibeknow在线创作视频的官方入口及网页版使用教程,涵盖PPT、PDF、Word等文档一键转讲解视频的核心操作,并整理了免费版水印规则与手机端浏览器访问指南,助你快速将知识内容视频化。

0

2026.09.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 169人学习

使用phpenv集成环境安装极致CMS
使用phpenv集成环境安装极致CMS

共2课时 | 273人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn