这主要是因为两种存储引擎处理行计数的方式不同。
MyISAM 引擎
- 存储行计数: MyISAM 存储引擎会在表的元数据中存储行的总数。这意味着当执行 SELECT COUNT(*) FROM table时,MyISAM 只需读取这个预先存储的值,非常快速。
- 无锁表扫描: 由于 MyISAM 表是非事务性的,它不需要处理事务和锁机制,因此在表扫描时速度较快。
InnoDB 引擎
- 实时计算行数: InnoDB 引擎不会在表的元数据中存储行的总数。相反,它需要遍历表中的数据行,逐个统计行数,以确保行计数的准确性。这是因为InnoDB 是一个支持事务的存储引擎,行数可能会因为未提交的事务而变化。
- 锁机制: InnoDB使用行级锁和多版本并发控制(MVCC),以支持高并发和事务。这些特性虽然提高了数据一致性和并发性能,但在执行全表扫描时,可能会带来额外的开销。
- 缓存机制: InnoDB有自己的缓存机制(缓冲池),它会缓存数据页和索引页,提高查询性能。然而,在进行全表扫描和计数时,这些缓存并不能显著加速计数操作。
事务A只修改数据,只要不提交,事务B就感觉不到数据发生了变化,所以得先处理事务,保证数据的一致性,所以innodb比较慢,而myisam数据是及时更新的,一旦数据发生了变化,在表的元数据中存储的行的总数也就发生变化了。