在MySQL性能调优过程中,索引字段的统计信息决定了查询优化器如何选择访问路径。统计信息主要包括索引的基数(Cardinality)、索引中各个字段的长度、索引是否唯一、以及索引的排列顺序等。当统计信息过时,优化器可能错误地选择全表扫描而非索引查找,导致查询明显变慢。因此,掌握查看和更新这些统计信息的方法,是数据库开发与运维的基本功。

一、使用SHOW INDEX命令查看索引统计
SHOW INDEX是最直接查看表索引信息的SQL语句,它会返回表中每个索引的基本统计,包括索引名、字段顺序、基数等。该命令从表的存储引擎层获取元数据,执行成本低,适合快速巡检。
例如,查看用户表上的所有索引统计,可以使用如下语句:
SHOW INDEX FROM user FROM test_db;
返回结果中的Cardinality列表示索引中唯一值的估计数量,也就是基数。对于组合索引,会按索引前缀依次列出每个前缀的基数。Sub_part显示索引前缀长度,如果为NULL则表示使用整个字段。这些数值是优化器计算选择率的重要依据。
需要注意的是,SHOW INDEX输出的基数是抽样估计值,并不绝对精确。在InnoDB中,基数通过随机采样页来估算,因此不同时间执行可能得到略有差异的结果,这属于正常现象。
二、通过information_schema查询字段级统计
如果需要在程序中批量获取索引统计,或者希望按条件过滤,information_schema.STATISTICS表比SHOW INDEX更灵活。它把每个索引字段拆成一行记录,方便做聚合分析。
以下查询可以列出指定表所有索引字段的基数与顺序:
SELECT INDEX_NAME, COLUMN_NAME, SEQ_IN_INDEX, CARDINALITY, SUB_PART, NON_UNIQUE FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = 'test_db' AND TABLE_NAME = 'user' ORDER BY INDEX_NAME, SEQ_IN_INDEX;
该视图中,SEQ_IN_INDEX表示字段在索引中的位置,从1开始;NON_UNIQUE为0代表唯一索引。通过关联TABLES视图,还能计算出基数与表行数的比例,从而评估索引区分度。比例越接近1,索引过滤效果通常越好。
除了STATISTICS,MySQL 8.0还提供了performance_schema.table_io_waits_summary_by_index_usage,可以统计索引的实际使用频次。结合统计信息与实际使用数据,能判断哪些索引属于冗余或从未使用。
三、利用sys库做索引统计洞察
sys系统库封装了performance_schema与information_schema的复杂查询,提供了更易读的索引统计视图,例如sys.schema_index_statistics和sys.schema_unused_indexes。
查看某表索引的估算行读取量,可以执行:
SELECT index_name, rows_read, rows_selected FROM sys.schema_index_statistics WHERE table_schema = 'test_db' AND table_name = 'user';
sys.schema_unused_indexes则会列出自性能数据收集以来未被使用的索引,辅助清理无用索引。但注意,该视图依赖performance_schema的采集,若未开启相应采集器则无数据。
使用sys库的好处是无需记忆底层表结构,且输出已做人性化命名。在排查慢查询时,先通过sys确认索引是否被使用,再比对STATISTICS中的基数,往往能快速定位优化器偏离预期的原因。
四、统计信息更新与维护
当表经历大量增删改后,统计信息可能失真。InnoDB默认开启innodb_stats_persistent,统计信息持久化到磁盘,并由后台线程自动更新,但大批量变更后仍需手动干预。
手动更新统计信息的标准命令是ANALYZE TABLE:
ANALYZE TABLE test_db.user;
该命令会重新采样并计算各索引基数,对持久化统计会写回mysql.innodb_index_stats等系统表。执行时会对表加读锁,大表上建议在低峰期操作。另外,通过SET GLOBAL innodb_stats_on_metadata=OFF可避免每次查询元数据都触发统计刷新,减少性能抖动。
对于分区表,可仅对单个分区执行ANALYZE,以缩小维护窗口。理解统计信息的生命周期,才能确保查看的数据真实反映表状态,从而让优化器做出正确决策。
五、常见误区与排查思路
一个常见误区是认为Cardinality就是精确去重数。实际上它只是基于采样页的估算,在字段重复值极多或数据倾斜时偏差可能较大。因此不能单凭SHOW INDEX的数值判断索引优劣,应结合EXPLAIN中的rows预估与实际返回行数。
另一个误区是频繁执行ANALYZE TABLE。过度更新不仅消耗IO,还可能因采样随机性导致基数波动,反而让执行计划不稳定。一般建议在明显数据量变化或执行计划突变时再手动更新。
排查索引统计相关慢查询的标准路径是:先用EXPLAIN观察是否走错索引,再通过SHOW INDEX或information_schema确认基数,最后视情况ANALYZE并对比前后执行计划。这样能形成闭环,避免盲目调参。
mysqlindex_statisticsinformation_schema修改时间:2026-08-09 11:42:32