MySQL 中COUNT(*),COUNT(1),COUNT(普通字段),COUNT(索引字段)的效率和区别?
目录一. 结论二. 在MyISAM 存储引擎中三. InnoDB 存储引擎中一. 结论结论一COUNT(普通字段)得到的结果可能与COUNT(1)COUNT(*)COUNT(主键字段)不一样因为普通字段可能为NULL为NULL则不会被统计进去后面三者则是按行统计只要一行中有一个字段不为NULL就会被统计进去结论二执行效率 COUNT(*) COUNT(1) COUNT(主键字段) COUNT(普通字段)二. 在MyISAM 存储引擎中在MyISAM存储引擎因为每张表中都有一个 mate 信息记录 row_count 的值不需要进行重新计算所以时间复杂度为O(1)而且MyISAM 存储引擎中只有表级锁能够确保数据的准确性和唯一性三. InnoDB 存储引擎中1在InnoDB存储引擎中表中没有具体的值来记录行数需要进行全表扫描都是需要用的时候再去进行COUNT计算所以时间复杂度为O(n)。原因就是因为InnoDB存储引擎的行锁支持高并发和MVCC的版本控制会导致统计数据不准确不像MyISAM那样是表级锁一次只能有一个线程操作。2在有非聚簇索引的情况下COUNT(1)COUNT(*)COUNT(主键字段)都是优先通过非聚簇索引统计数据因为非聚簇索引的B树不存储完整数据只有索引列和主键值数据量小IO成本低是优化器会优先选择的做法并且如果有多个非聚簇索引优化器会选择索引列最小(key_len最小)成本最低的一个来进行统计。COUNT(普通字段)就需要通过聚簇索引的B树来进行统计因为非聚簇索引的B树中没有普通字段无法通过非聚簇索引统计记录数。3在没有非聚簇索引的情况下COUNT(1)COUNT(*)COUNT(普通字段)COUNT(索引字段)都是通过聚簇索引来进行统计如果字段为NULL也是统计不进去的所以COUNT(普通字段)统计的结果一定小于等于 COUNT(1)COUNT(*)COUNT(索引字段) 的结果。