当前位置: 代码网 > it编程>数据库>Mysql > MySQL数据库统计函数COUNT的使用及说明

MySQL数据库统计函数COUNT的使用及说明

2024年07月18日 Mysql 我要评论
1. count 函数的作用数据库系统中 count(expr)用于统计数据行数,其主要作用为返回select语句检索的行中 expr 表达式的值不为 null 的行的数量,返回值是一个 bigint

1. count 函数的作用

数据库系统中 count(expr)用于统计数据行数,其主要作用为返回select语句检索的行中 expr 表达式的值不为 null 的行的数量,返回值是一个 bigint 值,如果查询结果没有命中任何记录则返回 0。

通常的使用方式主要有以下两种:

  • count(column) 表示统计对应列有值(不为空)的数据的行数
  • count(*) 表示统计结果集的总行数

2. count(*) 与 count(1) 与 count(column)

count(expr)统计的是 expr 不为 null的行数,而在count(column)count(1)count(*)三种用法中,expr 分别是列名常量*

这三个条件中常量是一个固定值,肯定不为null。

*可以理解为查询整行,所以肯定也不为null,只有列名的查询结果有可能是null。

故 count(1) 和 count(*) 可认为是直接查询符合条件的数据库表的行数,而count(column)表示的是查询符合条件的列的值不为null的行数。

  • 对于count(1)和count(*),官方的说法是在 innodb 引擎中二者完全一样,不存在快慢区别
  • count(column)的查询则比较简单粗暴,就是进行全表扫描,然后判断指定字段的值是不是为null,不为null则累加

相比 count(*),count(column) 多了一个判断所查询的字段是否为 null 的步骤,所以效率要比 count(*) 低

3. mysql 对 count 的优化

这些优化的前提都是查询语句中不包含 where 及 group by 限定条件

3.1 myisam 引擎优化

myisam 引擎的锁是表级锁,同一张表上的操作都是串行完成,故myisam做了一个简单的优化,就是把表的总行数单独记录下来

使用 count(*) 查询表的总行数时,直接返回这个记录下来的数值就可以了,当然前提是不能有where条件

myisam之所以可以把表的总行数记录下来供count(*)查询使用,是因为myisam数据库是表级锁,不会有并发的数据库行数修改,所以查询得到的行数是准确的

3.2 innodb 引擎优化

因为 innodb 支持事务,其中大部分操作都是行级锁,所以表的行数可能会被并发修改,在这种情况下将总行数记录下来的方式就不准确了。

因此 innodb 中使用 count( * ) 查询行数的时候,不可避免地要进行扫表,只能在扫表过程中来优化效率

我们知道,innodb 中索引分为聚簇索引(主键索引)和非聚簇索引(非主键索引)聚簇索引的叶子节点中保存的是整行记录,而非聚簇索引的叶子节点中保存的是该行记录的主键的值。

count(*)只是为了统计总行数,不用关心查到的具体值,如果在扫表的过程中选择一个成本较低的索引的话,那就可以大大节省时间。

显而易见,非聚簇索引要比聚簇索引小很多,所以 innodb 引擎会优先选择最小的非聚簇索引来扫表。

根据这个特性可知,建表的时候除了主键索引以外,创建一个非主键索引也很有必要

4. count 查询优化

假设有一张表t_user,里面有大概5000条记录,一个需求是统计 id 大于 20 的用户数量,以下两种写法效率大不相同

简单的条件查找,近乎扫描全表,表较小时效率很高,表数据较多就很耗时

select
    count( * ) 
from
    t_user
where
    id > 20;

另一个思路是先统计 id 小于 20 的记录,再使用总的行数减去该值就得到了结果。

这是因为查询优化阶段会把该类子查询当作常数处理,只需扫描 id < 20 的行,开销大幅减少

select
    ( select count( * ) from t_user ) - count( * ) 
from
    t_user 
where
    id < 20;

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持3w代码。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com