MySQL COUNT 函数及其优化

内容纲要

1、 count()的作用

计数函数,既可以统计某个列的数量又可以统计行数。

  1. 统计列Count(col_name),只统计非NULL列(在统计列值时(count(col)),列应该是非空的(NULL列不会计数);如果列为非空会优化器会将Count(col_name)转换为Count(*))
  2. 统计行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(第三版)

发表评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部