在不同的 MySQL 引擎中,count(*) 有不同的实现方式
- MyISAM引擎把一个表的总行数放在了磁盘上,因此执行count(*)的时候会直接返回这个数,效率很高
- InnoDB引擎就很麻烦,在执行count(*)的时候需要一行一行的从引擎中读出来,然后累计计数。
这里需要注意的是,count(*)是不带条件的,如果带where条件的话那么MyISAM也不会返回那么快。
多版本并发控制MVCC
悲观并发控制
乐观并发控制
mysql中的InnoDB引擎事务的默认隔离级别是可重复读(事务隔离级别)
可以看下事务隔离级别相关的文章
在保证逻辑正确的前提下,尽量减少扫描的数据量,是数据库系统设计的通用原则之一
show table status中的table_rows显示的行数是不准确的。误差率在40%~50%
小结
- MyISAM虽然count(*)很快,但是不支持事务
- show table status虽然很宽,但是存在误差
- InnoDB 需要扫描全表的数据,性能不佳
那么,现在有一个页面需要时常显示某个表的数据总条数,那么该怎么办呢?答案是,我们只能自己计数。
思路是你需要找一个地方把操作记录表的行数存起来
用缓存来保存计数
由于缓存系统和数据库系统属于分布式系统,无法保证一致性
用数据库来保存计数
可以利用数据库的事务特性来完成数据一致