当前位置: 首页 > 后端技术 > Java

完成面试-你能告诉我你通常如何在MySQL中使用COUNT()吗?

时间:2023-04-02 00:23:28 Java

大家好,我是程序员。相信在你的工作中,有很多函数需要用到count(*)来统计表中的数据行数。同时,对于一些大数据表,使用count也是手抖,往往结合cache来处理。那么,今天就来分析一下InnoDB中关于count的一些处理措施和优化。count常用的三种使用方式count(*)count(主键Id)/count(某字段)count(1)先count(*),count(主键Id)/count(某字段)和count(1)均表示满足条件的结果集中返回的总行数。它们的区别是:count(field)表示返回满足条件的数据行总数,参数“field”不为NULL,count(1)会统计表中的所有记录,包括该字段是NULL记录,但是它把所有的列都替换为1,不关注表中的具体列。count(*)包括所有列,相当于行数。统计结果时,不会忽略NULL值。接下来,让我们一一了解。对于count(主键id),InnoDB引擎会遍历整张表,提取每一行的id值,返回给server层。server层拿到id后,判断不可能为空,逐行累加。对于count(1),InnoDB引擎遍历整个表,但不取值。服务器层在返回的每一行中都放上一个数字“1”,判断不可能为空,逐行累加。如果只看这两种用法的区别,相信可以比较一下。Count(1)比count(primarykeyid)执行得更快。因为从引擎返回id涉及解析数据行和复制字段值,所以少了一个操作,节省了时间。同时,对于count(field):如果这个“字段”定义为NotNull,则逐行从记录中读取该字段,判断该字段不能为Null,则直接逐行累加;但是如果这个“Field”的定义允许为Null,那么在执行的时候,需要把具体的字段值取出来,然后进行判断,只有不为Null,才能进行累加。但是count(*)是个例外。MySQL专门对其进行了优化。MySQL每次发布新版本时,都会发布相应的ReleaseNotes。我们注意到它在版本5.7.2的发行说明中提到:InnoDB:SELECTCOUNT()FROMt语句现在调用存储引擎的单个处理程序调用来扫描聚集索引并将行计数返回给优化器。以前,行计数通常通过遍历较小的二级索引并为每个记录调用处理程序来执行。对存储引擎的单个处理程序调用以计算聚集索引中的行通常会提高SELECTCOUNT()FROMt的性能。但是,在大型聚集索引和明显较小的二级索引的情况下,与使用以前的未优化实现的性能相比,性能可能会下降。有关详细信息,请参阅InnoDB表的限制。简单的说:COUNT(*)会选择聚簇索引,调用内部处理函数,快速获取表的行数。因此,它也没有了需要获取值来判断是否为Null的计算操作,可以说效率得到了很大的提升。所以结论是:为了效率,count(field)