MySQL table_io_waits_summary_by_index_usage 中 NULL 索引名代表什么
来源:17golang原创
时间:2026-11-02 05:48:52 404浏览 收藏
MySQL table_io_waits_summary_by_index_usage 中 NULL 索引名代表什么
在 MySQL Performance Schema 的 table_io_waits_summary_by_index_usage 中看到 INDEX_NAME = NULL,通常不要马上下结论说“这张表没有索引”。它表示这组表 I/O 等待没有归属到某个具体索引;其中,插入操作会计入 NULL 这一组。真正判断索引是否被使用,需要把 NULL、PRIMARY 和具体二级索引放在同一张表的统计中比较。
本文只讨论这个字段的语义、查询方式和观察窗口,不把静态查询示例当作线上执行结果。
先把 NULL、PRIMARY 和“没有索引”分开
table_io_waits_summary_by_index_usage 按表索引聚合表 I/O 等待。INDEX_NAME = PRIMARY 表示事件归属于主键索引;具体名称表示归属于对应二级索引;NULL 则表示没有可关联的索引名。官方文档还特别说明,插入操作计入 INDEX_NAME = NULL。

因此,NULL 行可能来自写入路径,也可能来自没有被具体索引标识的表 I/O 事件。它不是执行计划的替代品,也不能单独证明查询走了全表扫描。
先按表名查看所有索引分组
排查时先缩小到一个 schema 和表,再保留 INDEX_NAME、读取次数和等待时间。下面的查询只读取汇总表,不改变采集配置。
-- 中文注释:按表和索引分组,先看 NULL、PRIMARY 与二级索引的完整分布
SELECT
OBJECT_SCHEMA,
OBJECT_NAME,
INDEX_NAME,
COUNT_STAR,
COUNT_READ,
COUNT_FETCH,
SUM_TIMER_WAIT
FROM performance_schema.table_io_waits_summary_by_index_usage
WHERE OBJECT_SCHEMA = 'app'
AND OBJECT_NAME = 'orders'
ORDER BY SUM_TIMER_WAIT DESC;
这里最重要的是保留 INDEX_NAME 原值,不要用 COALESCE(INDEX_NAME, '无索引') 后再作第一轮判断,否则会把“没有索引归属”和“表没有索引”混成一个概念。
怎样解释 NULL 行里的数字
如果 NULL 行的 COUNT_STAR 很高,先看业务操作是否包含大量 INSERT。插入会计入 NULL 组,所以这类数字可能只是写入量的反映。COUNT_READ、COUNT_FETCH 和 SUM_TIMER_WAIT 应结合操作类型、时间窗口和具体 SQL 一起解释,不能仅凭某一列的绝对值判断索引质量。
可以把结果按索引名做一个更适合阅读的投影,但建议保留原始值:
-- 中文注释:仅用于展示分组标签,原始 INDEX_NAME 仍应保留在明细查询中
SELECT
OBJECT_SCHEMA,
OBJECT_NAME,
CASE
WHEN INDEX_NAME IS NULL THEN 'NULL:未归属具体索引'
ELSE INDEX_NAME
END AS index_group,
COUNT_STAR,
COUNT_READ,
COUNT_FETCH,
SUM_TIMER_WAIT
FROM performance_schema.table_io_waits_summary_by_index_usage
WHERE OBJECT_SCHEMA = 'app'
AND OBJECT_NAME = 'orders'
ORDER BY COUNT_STAR DESC;
这个标签只是展示层解释,不会改变 Performance Schema 的统计含义。
建立观察窗口,再决定是否需要复查
汇总表保存的是累计信息。若需要观察一次发布或一段压测,可以先记录当前值,再清空指定汇总表的统计列,之后在固定窗口内采集。执行前要确认账号权限、采集窗口和业务影响。
-- 中文注释:重置表 I/O 汇总列,之后只观察新的时间窗口
TRUNCATE TABLE performance_schema.table_io_waits_summary_by_index_usage;
-- 中文注释:窗口结束后读取各索引组,比较新的读取次数与等待时间
SELECT
OBJECT_SCHEMA,
OBJECT_NAME,
INDEX_NAME,
COUNT_READ,
COUNT_FETCH,
SUM_TIMER_WAIT
FROM performance_schema.table_io_waits_summary_by_index_usage
WHERE OBJECT_SCHEMA = 'app'
AND OBJECT_NAME = 'orders'
ORDER BY SUM_TIMER_WAIT DESC;

常见误区
| 误区 | 更准确的判断 |
|---|---|
| 看到 NULL 就说表没有索引 | NULL 说明该事件没有具体索引归属;先结合表结构与操作类型。 |
| 把 NULL 行当成全表扫描次数 | Performance Schema 汇总不是执行计划,需结合 EXPLAIN 或实际 SQL 另行判断。 |
| 直接比较累计值 | 先明确采集起点和窗口,必要时重置汇总后再比较。 |
小结
INDEX_NAME = NULL 的核心含义是“这组表 I/O 等待没有对应的具体索引名”,而插入操作会计入这组。排查时保留 NULL、PRIMARY 和二级索引分组,先按表查看,再结合操作类型和固定观察窗口解释数字。只有当这些信息与表结构、SQL 和执行计划互相印证时,才适合继续讨论索引设计。
相关问题
NULL 行是不是一定代表全表扫描?
不是。它不是执行计划字段,不能单独推出全表扫描。
为什么 INSERT 会出现在 NULL 分组?
因为插入统计按官方定义计入 INDEX_NAME = NULL,不代表插入路径异常。
怎样避免累计数据影响判断?
固定观察窗口,必要时重置对应汇总表,再比较同一窗口内的计数和等待时间。
-
374 收藏
-
499 收藏
-
384 收藏
-
184 收藏
-
265 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习