MySQL COUNT 函数及其优化

1、 count()的作用

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

统计列Count(col_name),只统计非NULL列( 在 统 计 列 值 时 ( c o u n t ( c o l ) ) , 列 应 该 是 非 空 的 ( N U L L 列 不 会 计 数 );如果列为非空会优化器会将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:

MySQL COUNT 函数及其优化

class_video_isam:

在数据量都是3162560(300百万)条的场景,执行一下 select count(*) from class_video 和 select count(*) from class_video_isam:

MySQL COUNT 函数及其优化


myisam存储引擎0.001s,innodb存储引擎:23.381s

差别这么大,什么原因?

myisam存储引擎为了存储了这张表的总行数,而innodb需要逐行计数。但是myisam的这么快是有前提:即没有where子句,比如:select count(*) from class_video_isam where course_id=1540;

MySQL COUNT 函数及其优化


执行时间33.522秒。

MySQL COUNT 函数及其优化


4、 如何优化?

4.1 innodb count(*) 无where条件:

  • 增加统计表或者使用缓存。

4.2 有where条件:

  • 分析业务,减少扫描行数。
  • 可以根据该条件建立条件统计表。
  • 如果业务可以接受,那么使用近似行,近似行采用EXPLAIN语句,优化器会预估一个行数。

使用缓存。

5、  总结

  • 行数统计使用Count(*),统计列使用Count(col_name),如果col_name定义为非NULL,那么优化器会自动将Count(col_name)转换为Count(*)。
  • MyISAM和InnoDB计数略有不同,MyISAM直接存储了行数,所有全表行数统计非常快,而InnoDB需要扫描整张表。
  • 优化Count()主要是减少结果集扫描行数,比如:总是使用小的结果集;使用近似值(避免扫描);使用缓存;定时更新;汇总表。
  • 优化Count()还可以组合以上的方式,比如:定时更新,将汇总更新到汇总表,然后将汇总表内容写入缓存。

6、  参考

  1. 高性能MySQL(第三版)
上一篇:docker开启或关闭<开机自启容器>


下一篇:ubuntu系统安装docker