你好,我是吴计可师,一个工作十多年的后端开发,曾就职京东、阿里等多家互联网头部企业。
今天我来聊一聊mysql中,count相关的一些面试题
在 SQL 查询中,COUNT(*)、COUNT(1) 和 COUNT(id) 是常见的计数方式,它们的功能是统计记录数,但具体有什么不同?
作用:统计表中所有行的数量,包括所有列,不依赖具体字段。
特点:
它会对每一行进行统计,无论行中是否有 NULL。
在数据库底层实现中,COUNT(*) 不会逐一获取列值,而是通过优化器直接统计行数,因此性能通常是最优的。
适用场景:统计表的总行数,通常是最常用的计数方式。
示例:
SELECT COUNT(*) FROM employees;
结果:返回 employees 表的总行数。
作用:统计表中所有行的数量,与 COUNT(*) 的效果相同。
特点:
COUNT(1) 会把 1 作为一个常量列,类似于 COUNT(*),但实际不涉及表的具体字段。
在一些数据库(如 Oracle)中,COUNT(1) 的性能与 COUNT(*) 相同,因为它们都通过优化器直接统计行数。
注意:在某些情况下,数据库会对 1 做额外解析,但现代数据库优化器通常能将其优化为与 COUNT(*) 相同的效果。
适用场景:和 COUNT(*) 类似,通常用于统计总行数。
示例:
SELECT COUNT(1) FROM employees;
结果:返回 employees 表的总行数。
作用:统计某一列的非 NULL 值的行数。
特点:
只统计 id 列中值不为 NULL 的行。
如果列 id 中有 NULL,这些行不会被计入。
性能:需要读取 id 列的具体值,性能可能略低于 COUNT(*) 或 COUNT(1)。
适用场景:统计特定列的非空数据数量。
示例:
SELECT COUNT(id) FROM employees;
结果:返回 employees 表中 id 列非 NULL 值的行数,但是一般id如果是主键的话,也不为空
现代数据库:COUNT(*) 和 COUNT(1) 的性能几乎相同,因为优化器会将它们优化为直接统计行数的操作。
COUNT(id) 的性能取决于 id 列是否包含 NULL 值,以及该列是否被索引。
如果列有索引,性能可能会接近 COUNT(*)。
如果列中有大量 NULL 或未被索引,可能会稍慢。
推荐根据实际需求选择:
统计总行数:优先使用 COUNT(*) 或 COUNT(1)。
统计某列非空行数:使用 COUNT(id)。
6.1 在 MyBatis-Plus 中,默认生成的是哪种形式?
当使用 count() 方法进行查询时,默认会转换成 COUNT(*) 的 SQL 语句。
MyBatis-Plus 是基于 MyBatis 的增强框架,其核心是自动生成高效的 SQL,而 COUNT(*) 是数据库中最优化的方式之一,因此 MyBatis-Plus 默认采用这种写法。
假设有一个 User 表,结构如下:
id | name | age |
---|---|---|
1 | Alice | 25 |
2 | Bob | NULL |
// 使用 MyBatis-Plus 提供的 BaseMapper 接口
int totalUsers = userMapper.selectCount(null);
System.out.println("用户总数:" + totalUsers);
SELECT COUNT(*) FROM user;
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.isNotNull("age"); // 只统计 age 不为 NULL 的行
int count = userMapper.selectCount(queryWrapper);
生成的 SQL:
SELECT COUNT(*) FROM user WHERE age IS NOT NULL;
在大多数数据库系统(如 MySQL、PostgreSQL)中,COUNT(*) 的执行是基于当前事务的一致性快照,而不会实时更新数据。所以在执行 COUNT(*) 过程中插入的 10 条数据通常不会被计入。
具体来说:
默认情况下:如果 COUNT(*) 在一个事务中运行,数据库会使用该事务开始时的快照数据,这样就不会包括在 COUNT(*) 开始执行后插入的新数据。
隔离级别影响:事务隔离级别决定了并发查询时数据的可见性。在隔离级别为“可重复读”或更高的情况下,COUNT(*) 将基于查询开始时的快照,确保一致的结果,不会包括新插入的数据。
总结而言,大多数情况下,在 COUNT(*) 执行时插入的数据不会计入。
今天就分享到这儿,喜欢可以点赞,关注。你的关注是我前进的动力!