当前位置:首页 > 文章列表 > 数据库 > MySQL > MySQL 直方图统计信息怎样帮助优化器选择计划

MySQL 直方图统计信息怎样帮助优化器选择计划

来源:17golang原创 2026-10-28 23:15:37 0浏览 收藏

MySQL 直方图不是索引,也不会强制优化器选择某个索引;它补充的是列值分布信息。对于值分布倾斜、但仅靠普通统计信息难以估准选择率的列,优化器可以利用直方图更接近地估算过滤后会剩下多少行,从而比较不同执行计划。

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

要点速览
  • 用 ANALYZE TABLE ... UPDATE HISTOGRAM 为具体列生成统计信息,默认 100 个桶,也可以显式指定 1 到 1024 个桶。
  • 用 INFORMATION_SCHEMA.COLUMN_STATISTICS 查看直方图 JSON、类型、桶数和 sampling-rate,再用 EXPLAIN 对照优化器估算。
  • 直方图依赖数据分布的新鲜度;效果不合适时先重新生成,仍不需要时用 DROP HISTOGRAM 清除。

直方图到底补充了哪类统计信息

优化器需要估算条件会命中多少行,才能在索引、扫描、连接顺序等候选计划之间做比较。单一的基数或平均分布假设,在列值高度倾斜时可能不够:例如某个状态值占了绝大多数行,另一些状态几乎没有数据,同样的列却对应完全不同的过滤选择率。

直方图把列值范围或离散值整理成多个桶,并把这些分布摘要保存在数据字典中。用户通过 INFORMATION_SCHEMA.COLUMN_STATISTICS 读取视图,不直接操作底层数据字典表。它提供的是优化器参考信息,不是查询结果缓存,也不会替代合适的索引。

MySQL 过滤列、列值分布、直方图桶、COLUMN_STATISTICS、选择率估算与 EXPLAIN 计划的静态关系说明图
图1:结构说明图,展示列值分布、直方图统计与优化器计划判断的静态关系,不是运行截图。

用 ANALYZE TABLE 为目标列生成直方图

先挑选真正参与过滤、分布明显不均匀或估算经常偏差的列,而不是给整张表的所有列都建立直方图。最小语句如下:

-- 为 orders.status 生成直方图,帮助优化器了解状态值分布。
ANALYZE TABLE orders
  UPDATE HISTOGRAM ON status;

-- 需要更细的分布摘要时显式指定桶数量。
ANALYZE TABLE orders
  UPDATE HISTOGRAM ON status WITH 64 BUCKETS;

UPDATE HISTOGRAM 语法一次只针对一张表;同一语句可以列出多个目标列。WITH N BUCKETS 的 N 范围是 1 到 1024,省略时默认 100。桶越多不等于计划一定越好,还要考虑生成成本、数据规模和分布复杂度。

该操作需要目标表的 SELECT 和 INSERT 权限。MySQL 8.4 文档还说明,几何类型和 JSON 列不支持直方图,单列唯一索引覆盖的列也不能生成直方图;临时表和加密表同样不在可用范围内。

先查看 COLUMN_STATISTICS,再判断估算是否有依据

生成后不要只看语句返回成功,还要知道统计信息是否确实存在、采样比例是多少:

-- 读取指定表和列的直方图摘要,避免把别的表混在一起看。
SELECT SCHEMA_NAME,
       TABLE_NAME,
       COLUMN_NAME,
       HISTOGRAM
FROM INFORMATION_SCHEMA.COLUMN_STATISTICS
WHERE SCHEMA_NAME = DATABASE()
  AND TABLE_NAME = 'orders'
  AND COLUMN_NAME = 'status';

-- 只取采样比例,1.0 表示生成时读取了全部数据。
SELECT HISTOGRAM->>'$."sampling-rate"' AS sampling_rate
FROM INFORMATION_SCHEMA.COLUMN_STATISTICS
WHERE SCHEMA_NAME = DATABASE()
  AND TABLE_NAME = 'orders'
  AND COLUMN_NAME = 'status';

返回的 HISTOGRAM 是 JSON 对象,常见信息包括 histogram-type、number-of-buckets-specified、last-updated、null-values 和 sampling-rate。sampling-rate 小于 1 说明生成过程采用了采样,不能把桶看成完整数据的逐行复刻。

如果生成期间需要读取的数据超过 histogram_generation_max_mem_size,MySQL 会改为采样;可以通过这个字段判断当前直方图的依据是否足够覆盖业务数据。这里的判断重点是“统计信息是否新鲜、是否有采样、是否与当前过滤场景相符”,而不是单独追求一个更大的桶数。

MySQL ANALYZE TABLE、UPDATE HISTOGRAM、WITH N BUCKETS、AUTO UPDATE、sampling-rate 与 DROP HISTOGRAM 的静态维护边界图
图2:维护边界说明图,展示桶数、采样率和生命周期控制的静态关系,不是运行截图。

用 EXPLAIN 对照计划,别把直方图当成强制提示

直方图是否真正改变了优化器选择,要回到具体查询观察估算行数、访问方式和过滤条件。可以在生成前后分别保存同一条查询的计划:

-- 用同一条查询对照估算行数和访问方式,避免把查询文本也一起改掉。
EXPLAIN FORMAT=JSON
SELECT order_id, created_at
FROM orders
WHERE status = 'pending';

重点对照的是估算行数、过滤条件对应的选择率以及访问路径是否更符合数据分布。计划变化本身不是成功标准:如果直方图过期、采样不足,或者优化器基于新估算选择了更差的路径,查询仍可能变慢。应在接近真实数据量和真实条件的环境中,用同一条 SQL、同一组参数做前后对照。

直方图也不能表达任意列之间的相关性。两个条件分别看似稀疏,组合起来可能高度相关;单列直方图并不会自动得到完整的多列联合分布。因此它适合补充某个列的分布估计,不应被当成“有了统计信息就能解决所有计划问题”。

桶数量、采样与自动更新怎么取舍

小桶数适合分布简单、维护成本敏感的列;分布有多个明显密集区时,可以增加桶数,但要用 HISTOGRAM 的桶数和 sampling-rate 一起判断。只调大桶数而不关注数据是否采样,可能只是让摘要更复杂,并没有带来等比例的估算收益。

-- 让后续持久化统计更新时按同样桶数自动更新该列直方图。
ANALYZE TABLE orders
  UPDATE HISTOGRAM ON status
  WITH 64 BUCKETS AUTO UPDATE;

-- 如果自动更新带来的计划变化不符合预期,删除这一列的直方图。
ANALYZE TABLE orders
  DROP HISTOGRAM ON status;

AUTO UPDATE 会启用自动更新;不写时默认是 MANUAL UPDATE。自动更新依赖持久化统计信息的更新机制,并不意味着每次 DML 完成后直方图都会立刻同步。若数据刚完成大批量导入、分布发生明显变化且需要立即刷新,显式执行 ANALYZE TABLE 更直接。

常见问题

直方图会不会强制 MySQL 使用某个索引?

不会。它提供列值分布摘要,影响的是优化器的估算依据;最终计划仍由优化器结合成本、索引和其他条件决定。

桶数是不是越大越好?

不是。桶数要与分布复杂度、表规模、生成成本和采样情况一起看。先用默认值观察估算,再针对确有偏差的列调整。

什么时候应该删除直方图?

当数据分布已变化、统计信息长期过期,或对照同一查询发现新计划持续变差时,可以先重新生成;如果该列不再需要分布摘要,再执行 DROP HISTOGRAM 清除。

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