1,不同的引擎有不同的实现方式。myisam直接存在磁盘上,可以直接读取。innodb需要一行行读,再进行累计。
2,innodb因为mvcc(多版本并发控制)的原因,同一时刻不同回话查询的数据可能不一致,
3,show table status可以显示表行数,但是不准确。
4,所以如何计数呢:一是使用缓存,插入一行数据,key就加一,删除就减一,但是redis可能因为重启导致存在丢失更新情况,但即使redis正常工作也会出现数据不准确的问题:因为redis跟db无法支持分布式事务,所以在写的两次操作的中间环节进来一个读线程,无论先读db还是先读redis都可能会出现不准确的问题。
二是使用数据库另一张表进行计数。依靠的是事务之前的隔离性。更新记录数与添加新纪录在一个事务中,如果未提交事务,其中的操作对外面的事务是不可见的。注意代码中的顺序,要先添加新记录,再更新记录数,因为更新记录数会触发行锁,只有在事务提交的时候才会释放行锁,如果放在程序最后,会大大提高并发度。
5,count的几种方式的效率比较。count(*)~=count(1)>count(主键)>count(某一个字段)