Count 查询优化
面试官问:"COUNT(*) 和 COUNT(id) 有什么区别?哪个更快?"
小陈说:"COUNT(*) 快,因为它不用读取列。"
面试官追问:"InnoDB 和 MyISAM 的 COUNT(*) 性能差多少?"
小陈说:"...MyISAM 快?"
面试官继续追问:"为什么?"
小陈答不上来。
COUNT 查询看似简单,实则是 MySQL 中最容易踩坑的性能问题之一。千万级数据量的 COUNT(*) 可能需要几秒,而优化后的 COUNT 可能只需几毫秒。
一、COUNT(*) 的本质 🔴
1.1 COUNT(*) 的语义
1.2 各 COUNT 表达式的语义
1.3 COUNT(*) vs COUNT(id)
1.4 ❌ 错误示范
候选人原话:"MyISAM 的 COUNT(*) 比 InnoDB 快很多,所以可以用 MyISAM。"
问题诊断:MyISAM 快是因为它存了精确行数,但 MyISAM 不支持事务、锁粒度粗、崩溃恢复差。为了 COUNT(*) 快而选 MyISAM 是本末倒置。
【面试官心理】 这道题我会从 InnoDB 和 MyISAM 的区别切入。真正理解 MySQL 存储引擎的候选人,应该知道 MyISAM 快的原因,以及为什么 InnoDB 的 COUNT(*) 必须全表扫描。
二、InnoDB COUNT(*) 的执行过程 🔴
2.1 全表扫描
2.2 MyISAM 为什么快
2.3 性能对比
结论:InnoDB 没有取巧,必须全表扫描计数。
三、COUNT 优化策略 🟡
3.1 利用索引
3.2 限制范围
3.3 近似计数
3.4 计数器表
四、生产避坑 🟡
4.1 禁止 COUNT(*) 全表统计
4.2 深度分页的 COUNT
4.3 EXPLAIN COUNT
【面试官心理】 COUNT 优化是 MySQL 实战中的高频考点。能说清楚 InnoDB COUNT(*) 为什么必须全表扫描、并且能提出多种优化方案的候选人,说明他对 MySQL 的存储结构和索引机制有深入理解。