首页 >> 基础教程

在mysql中count(1)、count(*)、count(列名)在各种常用存储引擎中的差异?

      在 MySQL 中,COUNT(1)COUNT(*) 和 COUNT(列名) 的性能和行为因存储引擎不同而存在显著差异,主要涉及 MyISAM 和 InnoDB 两种常用引擎。以下是详细对比:


 一、MyISAM 引擎下的差异

MyISAM 引擎在磁盘上直接存储表的总行数,因此对 COUNT() 的优化极为高效:

  1. COUNT(*) 和 COUNT(1)

    • 行为:直接返回存储的总行数,无需扫描数据。

    • 性能:极快(时间复杂度 O(1))136

    • 限制:仅适用于无 WHERE 条件的查询;若带条件则退化为全表扫描。

  2. COUNT(列名)

    • 行为:

      • 若列是 NOT NULL:与 COUNT(*) 行为相同,直接返回总行数(优化生效)。

      • 若列允许 NULL:需扫描全表,跳过值为 NULL 的行。

    • 性能:

      • NOT NULL 列:与 COUNT(*) 相同(O(1))。

      • 可空列:较慢(需全表扫描)


二、InnoDB 引擎下的差异

InnoDB 因支持 MVCC(多版本并发控制),无法直接存储总行数(不同事务可见行数不同)。需扫描数据,但有优化策略:

  1. COUNT(*) 和 COUNT(1)

    • 行为:完全等价,均统计所有可见行(含 NULL 行)。

    • 优化:

      • 优先遍历最小的二级索引(体积小于主键索引),减少 I/O。

      • 若无二级索引,则扫描主键索引(聚簇索引)。

    • 性能:高效(利用索引优化)。

  2. COUNT(列名)

    • 行为:仅统计该列非 NULL 值的行

    • 性能:

      • 若列有索引:遍历索引(索引不存储 NULL 值),性能较好17

      • 若列无索引:全表扫描,性能最差。

      • 若列定义为 NOT NULL:无需判空,略快于可空列13



最新文章
mysql分页问题2025-08-04
千万数据先insert和先建索引哪个快2025-08-04
MySQL 中大小表关联查询如何优化2025-08-04
sql技巧-每个班年龄排前两名的人2025-08-03
MySQL 导致 cpu 飙升的话,要怎么处理呢?2025-07-29
MySQL 中为千万级大表添加字段2025-07-29
mysql中百万级别以上的数据如何删除2025-07-29
分库分表带来的问题2025-07-29
mysql中常用的分库分表中间件有哪些2025-07-29
mysql不停机扩容2025-07-29
备案号:蜀ICP备2023042032号-1