高效统计数据的最佳实践:对于MyISAM表,SELECT COUNT(*) 直接快速;InnoDB表避免COUNT(*)全表扫描,使用索引列COUNT或维持计数表;大表分页用子查询或keyseek;性能优化热议:加索引、读从库、分批count、用approximate count。
CSDN网友分享
MyISAM引擎的表在执行 COUNT(*) 时不需要做全表扫描,因为MyISAM 的表统计信息已经保存,所以执行非常快。但 InnoDB 因为不支持事务安全的 MyISAM 那样的表级统计信息,所以执行 COUNT(*) 时需要进行全表扫描。
知乎热议
innodb 表COUNT(*)效率低是众所周知的。如果表很大,COUNT(*) 会很慢,那么我们有以下几种方法:1. 如果是单独使用count,建议用mysql自带的信息_schema.tables的table_rows字段。这个字段是表的大概行数,并不是精确的数字。2. 如果表有状态字段,最好加上where来限制范围,比如:select count(*) from table where status != -1这样虽然还是全表扫描,但是扫描行数少很多。
博客园经验
对于count(1) 和 count(*) 速度一样都很快,不用纠结。count(id) 比它们快一点,但是差距不大。count(列) 速度最慢,特别是作用于无索引的列时。
阿里云开发者社区
误区一:COUNT(*) 和 COUNT(1) 性能差异很大。真相:现代数据库优化器对 COUNT(*) 和 COUNT(1) 处理相同,性能无差异。误区二:全表 COUNT 必然慢。真相:MySQL InnoDB 8.0+ 通过索引优化或采样估算加速。
Stack Overflow 中文讨论
大表千万级数据,COUNT(*) 卡死,用 SELECT COUNT(id) FROM table WHERE id > 0; 但如果id是自增主键,可能更快。或者建一张统计表,增删时同步更新count值,查询时直接读。
简书网友帖
性能优化技巧:1. 使用覆盖索引;2. 分区表;3. 异步统计;4. Redis 缓存计数;常见误区:忽略锁竞争、频繁全表count导致CPU暴涨。
掘金社区
网友热议:对于亿级表,SELECT COUNT(*) OVER() 在窗口函数中用,但实际还是慢。推荐用 Elasticsearch 做聚合统计,或ClickHouse这种OLAP数据库替换。
FAQ
Q: COUNT(*) 和 COUNT(1) 有什么区别?
A: 没有性能区别,优化器处理相同。
Q: 大表怎么快速count?
A: 用索引列count、维持影子表或缓存。
Q: InnoDB为什么count慢?
A: 无表级统计,全表扫描。
Q: 分页统计时怎么优化?
A: 用子查询或LIMIT结合key。