当前位置:首页 > 文章列表 > 数据库 > MySQL > MySQL 8.0 直方图统计何时能救回错误执行计划:从基线到验证

MySQL 8.0 直方图统计何时能救回错误执行计划:从基线到验证

来源:17golang原创 2026-07-27 12:05:04 0浏览 收藏

线上订单列表查询耗时突然从 180ms 涨到 1.6s,慢查询里最反常的点不是索引失效,而是 MySQL 预估只会命中几百行,实际却扫出了几十万行。碰到这种“看起来有合适索引,但执行计划完全不符合真实数据分布”的场景,MySQL 8.0 的列直方图可以先做小范围尝试验证。

要点速览

  • 直方图补充的是非索引列或者数据分布的估算信息,不会凭空创建索引。
  • 先用 EXPLAIN ANALYZE 记录预估行数和实际行数,再决定要不要生成直方图。
  • 生成之后要检查 INFORMATION_SCHEMA.COLUMN_STATISTICS,再用同一条查询做复测。
  • 数据分布变化、采样误差或者查询条件不匹配时,直方图可能起不到作用,必要时直接删掉即可。

先确认问题是“行数估错”,不是“缺索引”

示例场景是订单列表查询,只关心最近 30 天里处于指定状态的订单:

SELECT id, user_id, amount, created_at
FROM orders
WHERE status = '待人工复核'
  AND created_at >= NOW() - INTERVAL 30 DAY
ORDER BY created_at DESC
LIMIT 50;

假设 status 的值高度倾斜:绝大多数订单是“已完成”状态,只有很小一部分需要人工复核。先别急着加复合索引,先把当前的执行计划和真实扫行数记下来:

EXPLAIN ANALYZE
SELECT id, user_id, amount, created_at
FROM orders
WHERE status = '待人工复核'
  AND created_at >= NOW() - INTERVAL 30 DAY
ORDER BY created_at DESC
LIMIT 50;

重点看每个执行节点对应的 rows= 和 actual ... rows=。如果预估只有400行、实际返回280000行,而且慢的点正好出现在过滤或者排序节点,说明优化器手里的分布统计信息可能已经过时,或者精度太糙。

MySQL 订单状态倾斜导致估算行数与实际行数分叉的基线证据图

用最小成本实验生成 orders.status 列的直方图

直方图的作用是帮优化器搞清楚列值的真实分布,尤其适合条件列没有合适索引,或者普通索引的基数统计没法表达倾斜分布的场景。操作前先在可回滚的测试环境,或者业务低峰期做验证:

ANALYZE TABLE orders
  UPDATE HISTOGRAM ON status WITH 32 BUCKETS;

这条语句会把 status 的分布统计写入数据字典。桶数不是越大越好,第一轮验证用32个桶基本足够,桶数太大不仅会增加统计维护成本,还可能让小表的统计结果过度精细,反而干扰判断。

生成操作跑完之后,先确认数据库是不是真的存下了对应的统计信息:

SELECT SCHEMA_NAME, TABLE_NAME, COLUMN_NAME, HISTOGRAM
FROM INFORMATION_SCHEMA.COLUMN_STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
  AND TABLE_NAME = 'orders'
  AND COLUMN_NAME = 'status';

如果查不到对应的记录,别以为语句执行成功查询就一定会变快。大概率是权限不足、列名写错、统计信息缓存没刷新,也有可能这条查询本身就不适合用直方图优化。

用同一组参数对比执行计划的变化

复测的时候要保证SQL、数据快照和运行参数完全一致,至少记录三个核心数值:总查询耗时、预估行数、实际扫描行数。示例记录格式可以参考:

-- 记录复测时间,不要改写 WHERE 条件
EXPLAIN ANALYZE
SELECT id, user_id, amount, created_at
FROM orders
WHERE status = '待人工复核'
  AND created_at >= NOW() - INTERVAL 30 DAY
ORDER BY created_at DESC
LIMIT 50;

如果直方图生效,通常能看到过滤节点的预估行数会更贴近真实值,随之生成更合理的访问路径。别死盯着“用了哪个索引”判断效果,如果结果集本身就很大,执行计划变了但总耗时没降,说明瓶颈大概率在回表、排序、磁盘读或者返回的数据量本身。

MySQL 直方图写入 COLUMN_STATISTICS 后通过 EXPLAIN ANALYZE 对比前后计划的验证图

哪些场景不能把直方图当万能修复方案

第一,查询的主要过滤条件已经有选择性很好的联合索引,问题其实出在索引列顺序或者范围条件的设计不合理。第二,表内数据每天变化幅度很大,昨天生成的分布统计今天已经完全失真。第三,过滤条件写在函数里、有隐式类型转换或者套在复杂表达式里,统计信息没法覆盖真实的选择性。第四,真正的问题是查询返回了太多列,或者排序操作没法利用索引,只改行数预估根本不会减少I/O开销。

碰到这些情况,优先检查 SHOW INDEX FROM orders、表数据增长情况、排序节点开销和慢查询的真实样本。直方图是有明确依据的补充优化手段,不能替代正常的索引设计流程。

没效果的时候怎么恢复原有状态

如果复测之后看不到收益,或者上线之后数据分布已经发生偏移,可以直接删掉这一列的直方图:

ANALYZE TABLE orders
  DROP HISTOGRAM ON status;

撤销之后再跑一遍同一条 EXPLAIN ANALYZE,确认执行计划回到之前的预期状态。生产环境的变更还要记录执行时间、影响的表、复测SQL和回退结果;ANALYZE TABLE 默认会写入二进制日志,主从复制环境要结合业务低峰窗口评估操作影响。

相关问题

直方图会自动创建索引吗?

不会。它只提供列值分布的统计信息,索引还是要靠表结构设计和匹配查询条件来手动创建。

没有索引的列也能使用直方图吗?

可以。直方图的核心价值之一就是补充普通索引统计没法表达的列分布细节,但优化器最终会不会选用它的结果,还是要看执行计划和实际耗时表现。

生成直方图之后执行计划怎么没变化?

有可能是原执行计划本身就足够高效,也有可能查询的瓶颈根本不在行数选择性估算,或者统计信息没覆盖到真正影响计划走向的条件列。

应该多久重建一次直方图?

不要按固定天数盲目重建。以数据分布明显变化、执行计划异常回退或者慢查询指标恶化为触发条件,而且每次重建都要在目标查询上做前后效果复测。

把验证结果整理成可复用的小清单

做直方图实验最有价值的产物不是一条操作SQL,而是一组可回溯复查的证据:生成前后的 EXPLAIN ANALYZE、COLUMN_STATISTICS 记录、总耗时、数据量变化和回退验证结果。只有行数预估误差、访问路径和实际耗时都朝着预期方向改善,才值得把这个直方图留在生产环境。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
MySQL 日期范围筛选为什么不走索引:半开区间、函数包裹与 EXPLAIN 核对MySQL 日期范围筛选为什么不走索引:半开区间、函数包裹与 EXPLAIN 核对
上一篇
MySQL 日期范围筛选为什么不走索引:半开区间、函数包裹与 EXPLAIN 核对
Go 1.24 基准测试怎么迁移到 testing.B.Loop:避免 b.N 写法的测量误差
下一篇
Go 1.24 基准测试怎么迁移到 testing.B.Loop:避免 b.N 写法的测量误差
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之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模型性能。
    734次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    735次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    815次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    775次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    610次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码