内容目录
1、 count()的作用
计数函数,既可以统计某个列的数量又可以统计行数。
- 统计列Count(col_name),只统计非NULL列(在统计列值时(count(col)),列应该是非空的(NULL列不会计数);如果列为非空会优化器会将Count(col_name)转换为Count(*))
- 统计行Count(*),统计结果集的行数。
2、 会检查所有的列?
不是的,当我们使用count()的时候,通配符不会检查所有的列,而是直接统计所有的行数;count(col),当col为非空列时,会转换成count(*)。
3、 count() innodb与myisam对比
我们现在有两张表class_video和class_video_isam, class_video表存储引擎为innodb,class_video_isam存储引擎为myisam。class_video:
class_video_isam:
在数据量都是3162560(300百万)条的场景,执行一下
select count(*) from class_video
和
select count(*) from class_video_isam
myisam存储引擎0.001s,innodb存储引擎:23.381s
4、差别这么大,什么原因?
myisam存储引擎为了存储了这张表的总行数,而innodb需要逐行计数。但是myisam的这么快是有前提:即没有where子句,比如:select count(*) from class_video_isam where course_id=1540;执行时间33.522秒。
5、 如何优化?
5.1 innodb count(*) 无where条件:
* 增加统计表或者使用缓存。
5.2 有where条件:
* 分析业务,减少扫描行数。
* 可以根据该条件建立条件统计表。
* 如果业务可以接受,那么使用近似行,近似行采用EXPLAIN语句,优化器会预估一个行数。
* 使用缓存。
6、 总结
1. 行数统计使用Count(*),统计列使用Count(col_name),如果col_name定义为非NULL,那么优化器会自动将Count(col_name)转换为Count(*)。
2. MyISAM和InnoDB计数略有不同,MyISAM直接存储了行数,所有全表行数统计非常快,而InnoDB需要扫描整张表。
3. 优化Count()主要是减少结果集扫描行数,比如:总是使用小的结果集;使用近似值(避免扫描);使用缓存;定时更新;汇总表。
4. 优化Count()还可以组合以上的方式,比如:定时更新,将汇总更新到汇总表,然后将汇总表内容写入缓存。
5. 使用实时流处理框架订阅数据库binlog实时计算并写入到缓存系统中,比如:使用Apache Flink实时计算并写入到Redis中
7、 参考
1. 高性能MySQL(第三版)