count优化
MyISAM引擎: 把一个表的总行数存在了磁盘上,因此执行count()的时候会直接返回这个数,效率很高(前提条件是查询的时候不能有where条件) InnoDB引擎: 比较麻烦,执行count()的时候,需要把数据一行一行地从引擎里面读出来,然后累积计数
所以对于MySQL的InnoDB引擎来说,目前没有比较好的优化方法,但是有肯定是有的,优化思路: 自己计数
解决: 借助可以value形式的内存级别的数据库,例如redis,当我们执行插入数据时,把这个计数+1,当我们要从表中删除数据时,把这个计数-1 由我们自己去维护计数。由于过程比较繁琐,想学的就考虑去redis相关教程学哦
count()是一个聚合函数,对于返回的结果集,一行行地判断,如果count函数的参数不是null,累计值就+1,否则不加,最后返回累计值 count的几种使用方式,以及这几种方式之间的性能差异,如下
1、count(*)
select count() from tb_user;
分析如下 InnoDB引擎并不会把全部字段取出来,而是专门做了优化,不取值,服务层直接按行进行累加
2、count(主键)
select count(id) from tb_user;
分析如下 InnoDB引擎会遍历整张表,把每一行的主键id值都取出来,返回给服务层。服务层拿到主键后,直接按行进行累加,不用判断是不是null(主键不可能为null)
3、count(字段)
select count(profession) from tb_user;#如果字段值不是null才会+1,是null的话就对这个null值不计数
分析如下 (1)该字段有not null约束。InnoDB引擎遍历整张表把每一行的字段值都取出来,返回给服务层,服务层判断是否为null,如果不为null,就计数累加 (2)该字段没有not null约束。InnoDB引擎遍历整张表把每一行的字段值都取出来,返回给服务层,直接按行进行计数累加
4、count(任意数字)
select count(1) from tb_user;#查询返回的每一条记录,都会放一个1进去,然后服务层发现要计数的不是null,就计数+1
分析如下 InnoDB引擎遍历整张表,但不取值。服务层对于返回的每一行,放一个数字“1”进去,直接按行进行累加
总结:按照效率给上面四种使用方式进行评估: count(字段) < count(主键) < count(任意数字) ≈ count(),所以尽量使用count()