不同引擎下的count()函数
对于innodb引擎,count()函数的效率是O(N),走的是全表扫描,对于myIsam引擎,查询的时间复杂度是O(1),myisam引擎把一个表的总行数写在了磁盘上。因为innodb要支持MVCC,所以innodb需要返回多少行是不确定的
当然前面所说的是针对没有过滤条件的语句,对于有过滤条件的语句,myIsam也不能这么快
innodb引擎解决count()慢的方法
-
利用缓存做一个计数器
当我们第一次查询的时候,就将count()得到的结果放到缓存中,比如redis,然后在我们向表中插入数据或者删除数据的前/后进行redis中计数器的更新即可,这样就能够直接从缓存中获得count()的值了。但是这种方式由于更新redis和更新MySQL不是在同一个库中,所以可能存在数据逻辑不一致的问题,同时redis是内存数据库,redis崩溃也可能会导致数据丢失的问题
-
在mysql中专门建立一个表存储计数器字段
每次进行增加或删除数据时同样对计数表进行相应的增加或者删除,由于操作同样在数据库中,这是我们可以利用数据库的事务来保证数据逻辑的一致性
不同count()函数的效率对比
count()共有以下几个函数count(*),count(1),count(字段),count(id)
count(字段)函数在计算时,会出现字段为null的情况,这时就不计算该行
count()函数的执行有以下原则:
-
server层需要什么就给什么
-
innodb值提供必要的值
-
目前的优化器只优化了count(*)的语义是取行数,其他的语义没有做优化
count(字段/id) innodb都会将字段和id返回给server,由server进行判断,不为空则行数+1
count(1/*) innodb只会将扫描到的行返回,server直接执行行数+1
效率:count(*) = count(1) > count(id) > count(字段)