mysql-count原理
背景
统计一张表的总数量,是我们开发中常有的业务需求,通常情况下,我们都是使用select count(*) from table 语句来完成。随着业务数据的增加,你会发现这条语句执行的速度越来越慢,为什么它会变慢呢?
InnoDB和MyISAM是我们常用的MySQL存储引擎,所以主要对比一下count(*)在InnoDB和MyISAM中的实现:
·在MylSAM存储引擎中,把表的总行数存储在磁盘盘上,当执行select count(*) from t 时,直接返回总数据,
·在innoDB存储引攀中,盟MyISAM不一样,没有将总行数存储在磁盘上,当执行select count(*) from t 时,会先把数据读出来,一行一行的累加(null值过滤掉),最后返回总数量,
·在InnoDB中执行select count(*) from t语句时,MySQL优化器会找到最小的那棵索引树来遍历,这样可能就可以减少加载次数,在一定程度上提升了count(*) 的执行效率。
count语义
count():mysql server层聚合函数,对返回的结果集一行行判断,不是null,累计值就+1,不是就不+1,最后返回累计值。
不同count的用法
count(主键)、count(1)、count(字段)
innoDB为什么不能跟MyISAM引擎一样将数据总数存下来
官方文档:https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_count
因为Innodb支持事物,不同的事物隔离级别,在同一时刻可以看到不一样的行数,对每个事物来说只能看到当前事物可见的行数
count(*)、count(1)、count(id)、count(column)的区别
官方文档:https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_count
count(*):
MySQL 5.7.18 之前,通过扫描聚集索引来InnoDB
处理 语句。SELECT COUNT(*)
从 MySQL 5.7.18 开始, 通过遍历最小的可用二级索引来InnoDB
处理SELECT COUNT(*)
语句,除非索引或优化器提示指示优化器使用不同的索引。如果二级索引不存在,则直接走聚集索引。
count(1):
InnoDB
以同样的方式处理SELECT COUNT(*)
和SELECT COUNT(1)
操作。没有性能差异。
count(id):
count(id)是主健的情况,在引擎层read_set设置和模板构建中需要有id字段,innodb需要返回该字段,效率会有一定的下降,性能略低于count(*)、count(1)
count(column):
4、count(column)根据索引条件判断(是否可为空),且从引擎层取值需要返回server层并进行null值判断过滤,conut(id)、count(1)、count(*)没有这个过程,直接在引擎层一次拿到总次数
大数据量统计数量替代方案
show table status like '{table_name}'
各列说明
1.Name 表名称 2.Engine: 表的存储引擎 3.Version: 版本 4.Row_format 行格式。对于MyISAM引擎,这可能是Dynamic,Fixed或Compressed。动态行的行长度可变,例如Varchar或Blob类型字段。固定行是指行长度不变,例如Char和Integer类型字段。 5. Rows 表中的行数。对于非事务性表,这个值是精确的,对于事务性引擎,这个值通常是估算的。 6.Avg_row_length 平均每行包括的字节数 7.Data_length 整个表的数据量(单位:字节) 8.Max_data_length 表可以容纳的最大数据量 9.Index_length 索引占用磁盘的空间大小 10.Data_free 对于MyISAM引擎,标识已分配,但现在未使用的空间,并且包含了已被删除行的空间。 11.Auto_increment 下一个Auto_increment的值 12.Create_time 表的创建时间 13.Update_time 表的最近更新时间 14.Check_time 使用 check table 或myisamchk工具检查表的最近时间 15.Collation 表的默认字符集和字符排序规则 16.Checksum 如果启用,则对整个表的内容计算时的校验和 17.Create_options 指表创建时的其他所有选项 18.Comment 包含了其他额外信息,对于MyISAM引擎,包含了注释徐标新,如果表使用的是innodb引擎 ,将现实表的剩余空间。如果是一个视图,注释里面包含了VIEW字样。