likes
comments
collection
share

MySQL函数:Count

作者站长头像
站长
· 阅读数 15

本文正在参加「金石计划」

MySQL是一个流行的关系型数据库管理系统,其中,COUNT最常用的函数之一,它可以帮助用户快速获取某个表或查询的行数。本文将详细介绍COUNT函数的用法和性能对比。

count()

基本用法

  COUNT函数是一个聚合函数,它用于计算一个表或查询中的行数。在MySQL中,COUNT函数可以用于任何数据类型的列。

  基本语法如下:

SELECT COUNT(column_name) FROM table_name;

  其中,column_name 是要计算的列的名称,table_name 是表的名称。在执行COUNT 函数时,它会忽略列值为NULL的行,因此如果要计算包括NULL值的行数,则需要使用COUNT(*)函数:

SELECT COUNT(*) FROM table_name;

   我们先来创建user表使用下

mysql>  show create table  user;
+-------+---------------------------------+
| user  | CREATE TABLE `user` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL COMMENT '1',
  `age` int(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `nameIndex` (`name`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+---------------------------------+
mysql> select * from user;
+----+------+-----+
| id | name | age |
+----+------+-----+
|  0 ||   3 |
|  1 ||  12 |
|  2 ||  14 |
|  3 ||   6 |
|  4 ||   3 |
|  5 | NULL |   7 |
|  7 ||  19 |
+----+------+-----+
7 rows in set (0.06 sec)
mysql> select count(name) from user;
+-------------+
| count(name) |
+-------------+
|           6 |
+-------------+
1 row in set (0.06 sec)

mysql> select count(distinct name) from user;
+----------------------+
| count(distinct name) |
+----------------------+
|                    3 |
+----------------------+
1 row in set (0.06 sec)

使用场景

  除了简单的计算行数之外,COUNT 函数还可以与其他函数结合使用,以实现更复杂的统计。例如,可以使用GROUP BY语句将数据分组并计算每个组的行数。示例如下:

SELECT column_name, COUNT(*) FROM table_name GROUP BY column_name;

  在上面的查询中,将按照column_name列中的不同值进行分组,并计算每个组中的行数。结果将返回两列,第一列为不同的column_name值,第二列为每个组中的行数。

  在实际应用中,COUNT函数可以广泛应用于许多场景中。例如,它可以用于确定某个表或查询是否为空,或者用于计算某个列中的唯一值的数量。此外,它还可以用于统计某个时间段内的记录数量等等。

实现方式

  在不同的MySQL引擎中, count有不同的实现方式。

  • 对于MyISAM ,表存储了确切的总行数,可以非常快速地访问

  • 对于InnoDB, 对于返回的结果集,一行行地判断, 把每一行的 expr 值都取出来, 返回给server层。 server层拿到字段后, 判断!= NULL的, 就按行累加计数,最后返回累计值。

为什么InnoDB不跟MyISAM一样, 也把数字存起来呢?

  InnoDB不保留内部计数表中的行,因为并发事务可能在同时间里“看到”的是不同数量。由于多版本并发控制(MVCC)的原因, 应该返回多少行也是不确定的。

  如果近似行数就足够了,可以使用SHOW TABLE STATUS,通过索引统计的值采样来估算的。误差可能达到40%到50%;

MySQL函数:Count

性能差异

  从MySQL 8.0.13开始,InnoDBcount 会优先遍历最小普通索引,除非索引或优化器提示 指示优化程序使用不同的索引。如果普通索引不存在,则扫描聚集索引。

   count(*)、 count(主键id)、 count(字段)、count(1)等不同用法的性能, 有哪些差别?

  count(*)、count(主键id)、count(1)表示返回满足条件的结果集的总行数;

  count(字段)则表示返回满足条件的数据行里面, 参数“字段”不为NULL的总个数。

  • 对于count(主键id)InnoDB会选择占用存储空间最小的那个索引来执行查询, 然后取出每一行ID,判断是否为空,然后计数累加。 MySQL函数:Count

  • 对于count(1)、count(*)InnoDB引擎会使用占用存储空间最小的那个索引来执行查询, 但不取值。把每一行计数累加。

  • 对于count(非索引列): 优化器选择全表扫描

MySQL函数:Count

  • 对于count(普通索引列):选择包含我们指定的列的索引去执行查询,但是当前执行的索引并不一定是最小的。 MySQL函数:Count

小结

  最后结论是:按照效率排序的话,建议尽量使用count(*)

count(1) = count(*) > count(主键id) > count(索引字段) > count(非索引字段)
转载自:https://juejin.cn/post/7212889505371750460
评论
请登录