MariaDB 10.3 执行计划比 MySQL 5.7 慢怎么优化?

文章导读
MariaDB 10.3 与 MySQL 5.7 的优化器代码在 5.5 版本后分叉,执行计划差异通常源于统计信息偏差或优化器开关配置不同。建议先对比 EXPLAIN 输出,通过更新统计信息和调整 optimizer_switch 参数对齐执行路径,不要直接套用 MySQL 配置文件。
📋 目录
  1. A 命令速用版
  2. B 为什么会这样
  3. C 分步处理
  4. D 怎么验证是否生效
  5. E 常见坑
  6. F 常见问题
A A

MariaDB 10.3 与 MySQL 5.7 的优化器代码在 5.5 版本后分叉,执行计划差异通常源于统计信息偏差或优化器开关配置不同。建议先对比 EXPLAIN 输出,通过更新统计信息和调整 optimizer_switch 参数对齐执行路径,不要直接套用 MySQL 配置文件。

先说结论:性能差异多由优化器策略选择不同导致,而非引擎本身性能倒退,需针对具体 SQL 调整。

  • 先定位:对比两端 EXPLAIN 的 type、rows 估算和 Extra 字段差异
  • 先做:执行 ANALYZE TABLE 更新统计信息,检查 optimizer_switch 设置
  • 再验证:观察查询耗时和执行路径变化,确认无回归

命令速用版

以下命令用于快速查看执行计划差异和优化器状态,直接在客户端执行:

-- 查看执行计划
EXPLAIN FORMAT=JSON SELECT * FROM your_table WHERE id = 1;

-- 更新表统计信息
ANALYZE TABLE your_table;

-- 查看优化器开关
SHOW VARIABLES LIKE 'optimizer_switch';

-- 查看当前优化器成本估算
SHOW STATUS LIKE 'Last_query_cost';

为什么会这样

MariaDB 10.3 和 MySQL 5.7 使用了不同的优化器代码分支,导致成本计算模型存在差异。MariaDB 在 5.5 之后独立发展,引入了不同的索引合并策略和连接缓存机制,而 MySQL 5.7 强化了原生分区和 JSON 支持,两者的优化器开关默认值不完全一致。统计信息采样算法的不同也会导致 rows 估算值偏差,进而触发不同的执行路径选择,例如全表扫描而非索引查找。

分步处理

按顺序执行以下步骤,每步完成后检查是否改善,避免一次性修改过多变量。

1. 对比执行计划细节
在 MariaDB 10.3 和 MySQL 5.7 分别对慢查询执行 EXPLAIN FORMAT=JSON。重点对比 access_type、rows 估算值和 used_key_parts。如果 MariaDB 选择了全表扫描而 MySQL 使用了索引,记录差异字段。

2. 更新统计信息
执行 ANALYZE TABLE 表名 更新当前数据库的统计信息。旧版本的统计信息可能导致优化器误判数据分布。操作后重新执行 EXPLAIN 观察 rows 估算是否更接近实际数据量。

3. 调整优化器开关
检查 SHOW VARIABLES LIKE 'optimizer_switch' 输出。尝试在会话级关闭或开启特定策略,例如 set session optimizer_switch='index_merge=off'。每次只调整一个开关,避免组合效应导致问题复杂化。

4. 检查索引定义
确认两端数据库的索引结构完全一致,包括索引顺序和类型。MariaDB 可能支持某些 MySQL 5.7 不具备的索引特性,反之亦然。如有差异,使用 ALTER TABLE 对齐索引定义。

5. 回滚提醒
修改配置前记录原始值。如果调整 optimizer_switch 后性能下降,立即恢复默认值。生产环境建议在从库先验证。

怎么验证是否生效

执行优化后,通过以下指标确认效果:

MariaDB 10.3 执行计划比 MySQL 5.7 慢怎么优化?

1. 执行计划回归检查
再次运行 EXPLAIN,确认 type 字段变为 ref 或 range 而非 ALL。used_key_parts 应显示实际使用的索引列。

2. 查询耗时对比
使用 SHOW PROFILE 或慢查询日志记录查询耗时。对比优化前后的 Duration 值,确认耗时降低。

3. 状态变量监控
检查 Last_query_cost 状态变量,数值降低通常意味着优化器选择了成本更低的路径。观察 Handler_read_rnd_next 等计数器,确认全表扫描次数减少。

常见坑

1. 直接套用 MySQL 配置文件
MariaDB 的 my.cnf 参数与 MySQL 不完全兼容,直接复制可能导致启动失败或性能下降。需参考 MariaDB 官方文档调整参数。

2. 统计信息过期
大量数据变更后未执行 ANALYZE TABLE,导致优化器基于旧统计信息生成计划。建议设置定期自动分析任务。

3. 忽略会话级差异
全局配置修改可能不影响已建立的连接。验证时需新建连接或重启服务确保配置生效。

常见问题

MariaDB 10.3 能直接用 MySQL 5.7 的配置文件吗?

不建议直接套用,部分参数名和默认值不同,可能导致启动错误或性能异常。

如何强制 MariaDB 使用特定索引?

在 SQL 语句中使用 USE INDEX 或 FORCE INDEX _hint_,但长期方案应优化统计信息和索引结构。

升级后执行计划变差是普遍现象吗?

不是普遍现象,通常是个别 SQL 因统计信息或优化器策略变化导致,需个案分析。

optimizer_switch 修改后需要重启数据库吗?

会话级修改立即生效,全局级修改通常不需要重启但影响新连接,具体视参数而定。