悠悠楠杉
MySQL索引字段统计信息查询实战指南
在实际数据库性能优化中,索引统计信息就像汽车的仪表盘——它能直观反映索引的健康状况。今天我们就来深入探讨MySQL中那些查看索引统计信息的实用技巧。
一、SHOW INDEX:快速诊断索引状态
最直接的查看方式莫过于SHOW INDEX
命令。假设我们有个用户表user_profile
,执行以下命令:
sql
SHOW INDEX FROM user_profile;
你会看到类似这样的输出结果:
+--------------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| user_profile | 0 | PRIMARY | 1 | user_id | A | 98210 | NULL | NULL | | BTREE | | |
| user_profile | 1 | idx_email | 1 | email | A | 87650 | NULL | NULL | YES | BTREE | | |
+--------------+------------+-------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
几个关键字段值得关注:
- Cardinality
(基数):估算的唯一值数量,这个值直接影响查询优化器的决策
- Non_unique
:是否允许重复值(0表示唯一索引)
- Seq_in_index
:字段在联合索引中的位置
- Collation
:排序规则(A表示升序)
二、information_schema:更灵活的统计查询
当需要批量分析多个表的索引时,系统表information_schema.STATISTICS
更加强大:
sql
SELECT
table_name,
index_name,
column_name,
cardinality,
index_type
FROM
information_schema.STATISTICS
WHERE
table_schema = 'your_database'
ORDER BY
table_name, index_name, seq_in_index;
这个查询可以生成整个数据库的索引清单,特别适合定期巡检时使用。我曾在一个电商项目中通过这个查询发现,有张订单表的order_status
字段索引基数异常低,进一步排查发现该索引几乎没有被使用过。
三、ANALYZE TABLE:更新统计信息
MySQL的统计信息不是实时更新的,当数据变化超过10%时会自动更新。但有时我们需要手动刷新:
sql
ANALYZE TABLE user_profile;
执行后再次查看SHOW INDEX
,你会发现Cardinality
值已经更新。有个实际案例:某次大促后用户表新增了30万数据,但查询计划仍然使用旧统计信息导致性能下降,通过ANALYZE TABLE
立即解决了问题。
四、性能视图:MySQL 8.0的新武器
如果你在使用MySQL 8.0,不妨试试新的数据字典视图:
sql
SELECT
index_name,
count_read,
count_fetch
FROM
performance_schema.table_io_waits_summary_by_index_usage
WHERE
object_schema = 'your_db'
AND object_name = 'user_profile';
这个视图能显示索引的实际使用频率,比单纯看统计信息更有参考价值。某次优化中我们发现一个建了三年的联合索引从未被使用过,果断删除后写入性能提升了15%。
五、索引统计的底层原理
MySQL通过采样统计来估算基数(Cardinality),具体过程是:
1. 随机读取8个数据页
2. 统计每个页面上不同值的数量
3. 计算平均值乘以总页数
这种估算方式在数据分布不均匀时可能产生偏差。可以通过设置innodb_stats_persistent_sample_pages
增加采样页数来提高精度,但会增加ANALYZE操作的开销。
最佳实践建议
- 定期检查索引使用情况,特别是数据量变化大的表
- 重点关注Cardinality接近表记录数的索引(选择性高)
- 联合索引要注意字段顺序,可通过
Seq_in_index
确认 - 不要过度依赖统计信息,最终要以实际执行计划为准
记得去年优化一个政务系统时,发现某查询频繁使用到的索引基数显示为30万,但实际唯一值只有5个,这就是典型的统计信息失准案例。通过ANALYZE TABLE
结合FORCE INDEX
临时解决了问题,后续调整了采样参数才彻底解决。
掌握这些索引统计查询技巧,你就能在数据库优化中真正做到有的放矢,而不是盲目添加索引。毕竟好的数据库优化,从来都是数据说话。