Skip to main content
☘️ Septvean's Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

MySQL COUNT

MySQL 统计表的行数有多少条,有几种方式?每天统计一次推荐用什么方式?

一、为什么统计行数不简单?

  • InnoDB 不维护真实行数(只是近似值,COUNT(*) 会全表扫描)
  • MyISAM 维护了行数(COUNT(*) 很快)
  • 行数统计对大表可能非常慢,需要根据使用场景选择方案

二、统计行数的几种方式

1️⃣ COUNT(*) (最常用,但可能慢)

SELECT COUNT(*) FROM user;

特点:

  • 精确值
  • 全表扫描(大表慢)
  • InnoDB 会做行锁,可能影响并发

2️⃣ COUNT(主键列) / COUNT(列)

SELECT COUNT(id) FROM user;

特点:

  • 对 NOT NULL 列,效果与 COUNT(*) 一样
  • 对可 NULL 列,会忽略 NULL
  • InnoDB 性能依然慢(全表扫描)

3️⃣ 近似统计:INFORMATION_SCHEMA 或 sys 库

SELECT table_rows
FROM information_schema.tables
WHERE table_schema='test'
  AND table_name='user';

特点:

  • 非常快
  • 只是估算值
  • 适合大表做 每日统计 / 数据监控
  • 每天执行一次足够

4️⃣ 累计计数表(业务级方案)

  • 维护一个 行数统计表
  • 每次 INSERT / DELETE / TRUNCATE 同步更新
  • 适合大表 / OLAP 场景

示例:

CREATE TABLE table_count (
    table_name VARCHAR(64) PRIMARY KEY,
    row_count BIGINT
);

-- 每次增删同步更新
UPDATE table_count SET row_count = row_count + 1 WHERE table_name='user';

优点:

  • 统计实时
  • 无需全表扫描

缺点:

  • 需在应用或触发器维护
  • 容易出错(事务异常)

5️⃣ MySQL 8 新特性:统计信息辅助查询

  • ANALYZE TABLE user;
  • 可获取 估算行数、索引分布、数据分布
  • 可结合 EXPLAIN 做优化

三、每天统计一次推荐方式

  • 大表推荐:INFORMATION_SCHEMA.tables.table_rows 或 业务累计表
  • 中小表:COUNT(*) 精确统计没问题
  • 报表 / OLAP:每天一次,增量更新到统计表,避免高峰期扫描

四、性能优化建议

  1. 避免高峰期全表 COUNT

    • 影响事务并发
  2. 统计表 + 触发器或应用逻辑更新

    • 精准 + 高效
  3. 结合缓存(Redis / Memcached)

    • 监控 / 频繁查询不 hit 数据库
  4. 使用近似算法

    • HyperLogLog 等,用于大规模统计(百万级以上行)

五、常见问题

Q1:InnoDB 为什么 COUNT(*) 慢?

因为 InnoDB 不维护真实行数,需要全表扫描。

Q2:信息模式的 table_rows 能用吗?

可以,但只估算,不精确。

Q3:如何每天统计大表行数?

使用 table_rows 估算 + 累计表 + 定时任务,避免高峰扫描。

Q4:为什么 MyISAM COUNT(*) 快?

MyISAM 记录了表行数,直接返回,不扫描数据。

六、推荐方案总结

场景 推荐方式 精确 性能
小表 / 不频繁 COUNT(*) 可以接受
大表 / 日统计 table_rows / 累计表 ❌/✅
OLAP / 日报 累计表 + 增量
近似分析 HyperLogLog