直方图仅在字段无索引、值分布严重倾斜、预估行数与实际相差超10倍时才影响索引选择;若字段已有高选择性索引或条件含函数、分区不匹配、类型不支持等,直方图将被绕过。

直方图本身不参与执行计划的物理扫描,它只影响优化器对“WHERE条件能过滤掉多少行”的估算——这个估算一旦更准,索引选择就可能从全表扫描(ALL)变成索引查找(ref或range)。
什么时候直方图真能帮上索引选择?
它只在以下三个条件同时满足时起作用:
- 字段没建索引,但频繁出现在
WHERE条件里(比如status、category、region) - 该字段值分布严重倾斜(例如
'active'占 95%,其余 20 种状态共占 5%) -
EXPLAIN显示预估行数(rows)和实际扫描行数相差超 10 倍(如预估 1 行,实际扫了 28 万行)
注意:如果字段已有索引,且索引本身选择性高、统计信息新鲜,直方图基本不会改变执行计划——优化器优先信索引统计,直方图只是“备选参考”。
为什么建了直方图,EXPLAIN 还是走 ALL?
直方图不是魔法开关,它被绕过的情况很常见:
-
WHERE条件对列用了函数,如WHERE UPPER(status) = 'ACTIVE'或WHERE DATE(created_at) = '2026-06-01'—— 直方图基于原始列值构建,无法映射到函数结果 - 查询涉及分区表,且条件未精确匹配分区键(MySQL 8.0.19+ 修复部分,但跨分区或范围分区仍易失效)
- 直方图建在从库,而
information_schema.COLUMN_STATISTICS表不复制,主库执行计划和从库EXPLAIN结果不一致 - 字段类型为
JSON、GEOMETRY或启用了压缩的TEXT,MySQL 当前版本不支持为其建直方图
如何验证直方图是否生效并影响索引决策?
别只看 ANALYZE TABLE ... UPDATE HISTOGRAM 是否成功返回 OK,直接查元数据 + 对比执行计划:
- 确认直方图已写入:
SELECT HISTOGRAM FROM information_schema.COLUMN_STATISTICS WHERE TABLE_SCHEMA = 'your_db' AND TABLE_NAME = 'orders' AND COLUMN_NAME = 'status';—— 返回非空 JSON 才算真正落地 - 对比加直方图前后的
EXPLAIN FORMAT=JSON输出,重点看"rows"和"filtered"字段变化。若"filtered"从 33.33(默认假设)跳到 4.7(接近真实比例),说明优化器已采纳直方图 - 执行
ANALYZE TABLE orders;再查一次EXPLAIN—— 因为直方图不自动触发统计刷新,ANALYZE TABLE会强制重载直方图元数据
桶数设太高(如 >1000)反而会让优化器加载变慢、估算失真;字符串列平均长度超 200 字节时,建直方图可能报 ER_TOO_LONG_STRING,得先用 SUBSTRING(status, 1, 100) 截断再建——但这会损失精度,慎用。


















