面试官灵魂拷问:count(1)、count(*)、count(列)到底差在哪?MySQL 性能翻车现场

那天有个朋友去面试,回来就跟我吐槽:"面试官问了个count的问题,我直接懵了!" 问题很简单:"count(1)、count(*)count(列)有什么区别?" 我朋友自信满满地回答:"count(1)最快,count(*)最慢,count(列)中等"

结果面试官笑了笑,说了句"再回去研究研究吧" 如果你也是这么想的,那今天这篇文章就是为你写的!

先说结论:别再用count(1)了!

我知道这跟很多人的认知完全相反 但事实就是:在MySQL中,count(*)才是性能最好的!

是的,你没看错 不是count(1),而是count(*)

实战见真章:来看测试结果

我在本地建了个测试表,插了100万条数据 然后分别用三种方式count:

sql 复制代码
-- 创建测试表
CREATE TABLE test_count (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    age INT,
    is_deleted TINYINT DEFAULT 0
);

-- 插入100万条测试数据

-- 开始测试
SELECT COUNT(*) FROM test_count;
SELECT COUNT(1) FROM test_count;
SELECT COUNT(id) FROM test_count;
SELECT COUNT(name) FROM test_count;

执行时间基本一模一样!

为什么count(*)是性能最好的?

其实在MySQL官方文档里早就说过了: InnoDB引擎会对count(*)count(1)做完全一样的优化

也就是说: count(*) = count(1) > count(列)

为什么count(列)会慢一点?因为count(列)需要判断这个字段是不是NULL!不是NULL才计数,是NULL就跳过

count(*)count(1)根本不管这些,直接数行数就完事了。

业务场景中的坑

来看个实际案例: 某天我接到个需求:统计用户表中有效用户数。于是我顺手写了:

sql 复制代码
SELECT COUNT(is_deleted) FROM users WHERE is_deleted = 0;

结果查询超时了!为什么呢? 因为is_deleted字段没索引! count(列)的时候,MySQL只能全表扫描

但如果改成:

sql 复制代码
SELECT COUNT(*) FROM users WHERE is_deleted = 0;

虽然还是全表扫描,但至少不用判断每个字段的NULL值了,速度能快那么一丢丢。

优化方案

其实最好的办法是:给筛选条件字段加索引!

sql 复制代码
ALTER TABLE users ADD INDEX idx_is_deleted (is_deleted);

然后再count,速度直接起飞!

count(DISTINCT 列)

这时候面试官又问了:"如果我想统计某列有多少个不同的非NULL值,该用什么?"

正确答案是:count(DISTINCT 列)

sql 复制代码
-- 统计age有多少个不同的值(跳过NULL)
SELECT count(DISTINCT age) FROM test_count;

总结

  1. count(*)和count(1)没区别,用哪个都行(但推荐count(*),因为这是SQL标准写法)
  2. count(列)会慢一点,因为它要排除NULL值
  3. 最大的性能瓶颈在索引,没索引count啥都慢

下次面试再遇到这个问题,你可以自信地告诉面试官: "count(*)count(1)性能一样,但count(列)需要额外判断NULL值"。 保证让面试官刮目相看!

希望这篇文章对你有帮助~如果有其他问题,欢迎在评论区留言!

我是大华,专注分享前后端开发的实战笔记。关注我,少走弯路,一起进步!

📌往期精彩

《写给小公司前端的 UI 规范:别让页面丑得自己都看不下去》

《只会写 Mapper 就敢说会 MyBatis?面试官:原理都没懂》

《别再手写判空了!SpringBoot 自带的 20 个高效工具类》

《别学23种了!Java项目中最常用的6个设计模式,附案例》

《Vue3+TS设计模式:5个真实场景让你代码更优雅》

相关推荐
二哈赛车手7 小时前
新人笔记---ApiFox的一些常见使用出错
java·笔记·spring
栗子~~8 小时前
JAVA - 二层缓存设计(本地缓冲+redis缓冲+广播所有本地缓冲失效) demo
java·redis·缓存
YDS8298 小时前
DeepSeek RAG&MCP + Agent智能体项目 —— RAG知识库的搭建和接口实现
java·ai·springboot·agent·rag·deepseek
candyTong9 小时前
Claude Code 的 Edit 工具是怎么工作的
javascript·后端·架构
未若君雅裁9 小时前
MyBatis 一级缓存、二级缓存与清理机制
java·缓存·mybatis
AI人工智能+电脑小能手10 小时前
【大白话说Java面试题 第65题】【JVM篇】第25题:谈谈对 OOM 的认识
java·开发语言·jvm
GetcharZp10 小时前
GitHub 2.4 万 Star!D2 正在重新定义程序员画图方式
后端
阿维的博客日记10 小时前
Nacos 为什么能让配置动态生效?(涉及 @RefreshScope 注解)
java·spring
雨辰AI10 小时前
SpringBoot3 + 人大金仓读写分离 + 分库分表 + 集群高可用 全栈实战
java·数据库·mysql·政务
辰海Coding12 小时前
MiniSpring框架学习-完成的 IoC 容器
java·spring boot·学习·架构