为何SHOW INDEX显示CARDINALITY为1?是否引发慢SQL?
索引基数异常与慢SQL问题分析
一、CARDINALITY值为1的原因
CARDINALITY是InnoDB对索引基数(唯一值数量)的估算值,而非精确值,临时变为1的原因主要有:
- 统计信息采样偏差:InnoDB通过采样数据页估算索引基数,当采样的少量数据页中恰好全是重复值(比如某批写入数据的
gs_id、bill_date、type、account_user_id组合重复),就会导致估算出的基数为1。 - 统计信息未及时刷新:InnoDB默认在表数据变更量超过10%时自动刷新统计信息,若未达到触发阈值,旧的错误估算值会保留。你提到次日自动恢复,就是因为MySQL触发了统计信息的自动刷新,重新采样后得到了正确结果。
- 持久化统计信息临时异常:若开启了
innodb_stats_persistent,统计信息存储在innodb_index_stats表中,该表数据临时读取异常也可能导致基数显示错误,不过这种情况概率较低。
二、是否为慢SQL的诱因
是的,这是导致慢SQL的直接原因:
MySQL优化器选择索引的关键依据是索引区分度(由基数体现),当基数被估算为1时,优化器会判定该索引几乎无法过滤数据,会放弃使用uk_gsid_billdate_type_accountid索引,转而执行全表扫描。而表t1的自增ID已达3.7亿级,全表扫描的IO和CPU开销极大,必然导致SQL执行超时,触发慢SQL告警。
快速修复与优化建议
- 手动刷新统计信息:执行
ANALYZE TABLE t1;强制更新索引统计数据,修正基数估算值。 - 强制指定索引:在SQL中添加
FORCE INDEX(uk_gsid_billdate_type_accountid),强制优化器使用目标索引,临时规避慢SQL问题。 - 调整统计参数:适当增大
innodb_stats_sample_pages参数值(默认是20),提升采样的准确性,减少估算偏差;确保innodb_stats_persistent开启,让统计信息持久化存储,降低异常概率。
内容的提问来源于stack exchange,提问作者HuangGuojun
相关产品推荐
相关产品推荐

