当前位置:首页 > 文章列表 > 数据库 > MySQL > MySQL histogram 怎样辅助没有合适索引的列估算

MySQL histogram 怎样辅助没有合适索引的列估算

来源:17golang原创 2026-10-26 01:23:47 0浏览 收藏

当一张订单表的 status 列没有合适的单列索引时,MySQL 仍然需要估算“这个条件大概会命中多少行”。这时可以用 histogram 保存列值分布,让优化器在选择连接顺序、过滤方式和扫描计划时少一些盲猜。

官方资料:https://dev.mysql.com/doc/refman/8.4/en/optimizer-statistics.html

要点速览
  • histogram 是列值分布统计,不是索引;它改善的是基数估算,不能直接让全表扫描变成索引查找。
  • 对没有合适索引的列,可以用 ANALYZE TABLE ... UPDATE HISTOGRAM 建立统计,再从 INFORMATION_SCHEMA.COLUMN_STATISTICS 查看。
  • 最终要用 EXPLAIN 对照 rows、过滤条件和访问路径;统计过期、采样过低或条件不适用时,估算仍可能失真。

histogram 解决的是“估算错”,不是“增加索引”

先把职责分开。索引提供一条可访问的数据结构,histogram 则记录某个列的值分布。没有合适索引时,优化器仍可能选择扫描,但它可以借助分布统计估算过滤后的行数,从而更合理地比较扫描、连接顺序和后续过滤成本。

MySQL 官方文档明确把 histogram 主要定位在非索引列上;对于已经有索引的列,优化器可能通过 index dive 或 range optimizer 得到更直接的估算,histogram 不一定更有用。因此,不能把“建立 histogram”写成“给列补上了索引”,也不能只看到统计信息存在就断言查询一定变快。

下面把订单表的 status 当作示例列。假设业务查询经常筛选它,但当前没有合适的单列索引;这篇只观察估算信息,不把示例输出描述成已经在某台机器上实测的结果。

用 ANALYZE TABLE 建立并查看 histogram

先为目标列生成一个有限数量的桶。桶数量不是越大越好:它需要在分布表达能力和统计维护成本之间取平衡。MySQL 8.4 中 N 的范围是 1 到 1024,省略时默认使用 100。

-- 为没有合适单列索引的状态列建立持久化分布统计。
ANALYZE TABLE shop_orders
  UPDATE HISTOGRAM ON status WITH 32 BUCKETS;

-- 查看统计类型、桶数量和采样率,判断统计是否真的存在。
SELECT SCHEMA_NAME,
       TABLE_NAME,
       COLUMN_NAME,
       HISTOGRAM->>'$."histogram-type"' AS histogram_type,
       HISTOGRAM->>'$."number-of-buckets-specified"' AS bucket_count,
       HISTOGRAM->>'$."sampling-rate"' AS sampling_rate
FROM INFORMATION_SCHEMA.COLUMN_STATISTICS
WHERE TABLE_NAME = 'shop_orders'
  AND COLUMN_NAME = 'status';

COLUMN_STATISTICS 暴露的是一个 JSON 形式的 histogram。这里的查询只做观察,不要求先把完整 JSON 复制出来;重点是确认列名、类型、桶数量和采样率是否与当前维护动作相符。

MySQL 没有合适索引的列、ANALYZE TABLE、histogram、COLUMN_STATISTICS 与优化器估算之间的静态关系说明图
图1:结构说明图,展示非索引列的分布统计如何进入 COLUMN_STATISTICS 并被优化器用于估算,不是运行截图。

用 EXPLAIN 判断估算有没有被改善

建立 histogram 后,应该回到实际查询的执行计划。示例查询只用于展示观察入口:

-- 用执行计划观察过滤行数估算,不把示例输出当作实测结论。
EXPLAIN SELECT id, created_at, total_amount
FROM shop_orders
WHERE status = 'PAID'
  AND created_at >= '2026-01-01';

重点看三件事:第一,访问路径是否仍然是预期的表扫描或其他路径;第二,rows 是否反映了 status = 'PAID' 的实际分布,而不是把每个状态都当成差不多;第三,filtered 与其他条件叠加后,估算是否出现明显偏差。没有合适索引时,histogram 不能消除扫描本身,但更可信的行数会影响优化器对连接顺序和中间结果规模的判断。

观察项能说明什么不能说明什么
rows优化器预计检查的行数范围不是实际返回行数,也不是耗时
访问类型与键列计划选择了哪种访问路径不能单独证明 histogram 造成了变化
filtered剩余条件的估算过滤比例不是业务数据的精确统计报表

如果前后计划差异很小,也不代表 histogram 无效:可能是当前条件本身已经容易估算,或者 range optimizer 已经优先处理了这个条件。更稳妥的做法是保存建立统计前后的 EXPLAIN 结果,再结合真实数据分布和查询目标判断。

MySQL histogram 的列值分布、桶数量、采样率、rows 估算和计划选择边界说明图
图2:边界说明图,对比分布统计、采样率与 EXPLAIN 行数估算之间的关系,不是执行结果截图。

采样、自动更新和删除都要有边界

histogram 不是永久正确的快照。数据持续变化后,列值分布会逐渐偏离上次统计;如果生成时受 histogram_generation_max_mem_size 限制而采用采样,还要关注 sampling-rate。采样率较低时,稀有值和突变分布可能更容易被估算遗漏。

-- 让后续 ANALYZE TABLE 或 InnoDB 持久化统计重算时更新该 histogram。
ANALYZE TABLE shop_orders
  UPDATE HISTOGRAM ON status WITH 32 BUCKETS AUTO UPDATE;

-- 业务不再需要这份列统计时,显式删除它。
ANALYZE TABLE shop_orders
  DROP HISTOGRAM ON status;

AUTO UPDATE 是 MySQL 8.4 提供的管理方式;没有指定时默认是 MANUAL UPDATE。另外,histogram 不能用于所有列:官方文档列出了 JSON、空间类型、临时表和单列唯一索引等限制。对数据变化快的状态列,更新时机要和发布、归档或批量导入节奏一起设计。

常见问题

没有索引时建立 histogram,会不会让查询直接走索引?

不会。histogram 只提供列值分布统计,不创建 B-Tree 或其他访问结构;它可能改善优化器的行数估算,但最终仍可能选择扫描。

桶数量设置得越大,估算就一定越准吗?

不一定。桶更多可以表达更细的分布,但也会增加统计维护成本;应结合数据规模、分布变化和 EXPLAIN 的估算偏差调整。

为什么 COLUMN_STATISTICS 有记录,计划却没有明显变化?

优化器可能已经有更适合的 range 估算,或者当前条件不属于 histogram 的有效使用场景。记录存在只证明统计已保存,不证明每条查询都会采用它。

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