首页 数据库 【面试题】MySQL 中 count(*)、count(1) 和 count(字段名) 有什么区别

【面试题】MySQL 中 count(*)、count(1) 和 count(字段名) 有什么区别

一、快速结论(先看结论再看分析)
方式 作用 效率 一句话总结
count(*) 统计所有行数  最高 我是专业的!我为统计而生
count(1) 统计所有行数  同样高效 我是 count(*) 的马甲兄弟
count(列名) 统计该列非 NULL 的行数 较慢 我挑剔,我只数非空值
结论:用 count(*) 就对了!

二、代码示例:亲测三兄弟的差别
准备测试数据
-- 创建测试表
CREATE TABLE user_test (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
age INT,
email VARCHAR(100)
);

-- 插入测试数据(故意插入一些NULL值)
INSERT INTO user_test (name, age, email) VALUES
('张三', 25, 'zhangsan@example.com'),
('李四', NULL, NULL),
('王五', 30, 'wangwu@example.com'),
(NULL, 28, 'unknown@example.com'),
('赵六', 35, NULL);
测试查询
-- 查看表中的数据
SELECT * FROM user_test;
/*
+----+--------+------+--------------------+
| id | name | age | email |
+----+--------+------+--------------------+
| 1 | 张三 | 25 | zhangsan@example...|
| 2 | 李四 | NULL | NULL |
| 3 | 王五 | 30 | wangwu@example.com |
| 4 | NULL | 28 | unknown@example.com|
| 5 | 赵六 | 35 | NULL |
+----+--------+------+--------------------+
*/

-- 测试1:count(*) 统计所有行数
SELECT count(*) FROM user_test; -- 结果:5
-- 翻译:"老板,我有多少行数据?全都要!"

-- 测试2:count(1) 统计所有行数
SELECT count(1) FROM user_test; -- 结果:5
-- 翻译:"老板,你给我个固定值1,我数有多少个1"

-- 测试3:count(列名) 统计非NULL的行数
SELECT count(name) FROM user_test; -- 结果:4 (NULL的那行没算)
SELECT count(age) FROM user_test; -- 结果:4 (NULL的那行没算)
SELECT count(email) FROM user_test; -- 结果:3 (两个NULL都没算)
-- 翻译:"我只数有身份证的人,黑户不算"
三、深入剖析:它们到底有啥不同?
1. 语义区别(最重要的区别!)
-- count(*) 是 SQL 标准写法
-- 意思:给我这个表有多少行数据
-- 相当于:"这个会议室有多少个座位?"

-- count(1) 是 count(*) 的一种写法
-- 意思:统计有多少个1
-- 相当于:"给每个座位发个苹果,最后数苹果"

-- count(列名) 是统计该列非NULL值的数量
-- 意思:这个会议室有多少人带了手机
-- 相当于:"检查每个座位,如果有人带了手机就计数"
2. 性能区别(神话与现实)
传说中的误解:
"count(1) 比 count(*) 快"
"count(主键) 最快"

现实真相:
MySQL 5.7 及以后版本:

count(*) 和 count(1) 性能完全相同
MySQL 优化器会把它们当作一回事
查看执行计划证明:

EXPLAIN SELECT count(*) FROM user_test;
EXPLAIN SELECT count(1) FROM user_test;
EXPLAIN SELECT count(id) FROM user_test;
-- 你会看到:前两个的执行计划完全一样!
性能排序(一般情况):

count(*) ≈ count(1) 
count(主键列) 
count(非主键有索引列) 
count(非主键无索引列) 
为什么 count(列名) 可能更慢?

-- 假设 email 列有索引
SELECT count(email) FROM user_test;
/*
MySQL 需要:
1. 读取索引(如果该列有索引)
2. 检查每个值是否为 NULL
3. 只计数非 NULL 的

如果 email 列没有索引:
1. 读取整行数据(比 count(*) 读的更多)
2. 检查 email 是否为 NULL
3. 只计数非 NULL 的
*/
3. 特殊情况分析
-- 情况1:所有列都不允许NULL
CREATE TABLE user_not_null (
id INT PRIMARY KEY NOT NULL,
name VARCHAR(50) NOT NULL
);
-- 这时候:count(*) = count(id) = count(name)

-- 情况2:空表 vs NULL值
CREATE TABLE empty_table (id INT);
SELECT count(*) FROM empty_table; -- 结果:0
SELECT count(id) FROM empty_table; -- 结果:0

INSERT INTO empty_table VALUES (NULL);
SELECT count(*) FROM empty_table; -- 结果:1
SELECT count(id) FROM empty_table; -- 结果:0
四、实际工作中的选择指南
场景1:统计总行数
-- 正确做法
SELECT count(*) FROM orders;

-- 错误做法
SELECT count(order_id) FROM orders; -- 万一有NULL呢?
SELECT count(1) FROM orders; -- 能用,但不是标准
场景2:统计有效数据数量
-- 统计有多少用户填写了邮箱
SELECT count(email) FROM users; -- 这个场景就该用 count(列名)

-- 统计已完成订单数量(假设 status=2 是已完成)
SELECT count(*) FROM orders WHERE status = 2; --
场景3:统计非重复值
-- 统计有多少个不同的城市
SELECT count(DISTINCT city) FROM users; -- count + DISTINCT

-- 统计有多少个城市,排除 NULL
SELECT count(DISTINCT city) FROM users; -- DISTINCT 会自动排除 NULL
五、性能优化技巧
1. 大表优化方案
-- 方案1:使用近似值(适用于统计概览)
SELECT TABLE_ROWS
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'your_db' AND TABLE_NAME = 'big_table';

-- 方案2:分页总数缓存(适用于列表页)
-- 第一次查询时缓存总数,后面定时更新

-- 方案3:使用汇总表
CREATE TABLE stats_daily (
date DATE PRIMARY KEY,
user_count INT,
order_count INT
);
2. 索引优化
-- 为 count(列名) 创建索引
CREATE INDEX idx_email ON users(email);

-- 但注意:count(*) 不一定需要索引,InnoDB有优化
六、有趣比喻帮你记忆
汉堡店排队比喻
-- 有10个人在排队买汉堡

count(*) = "队列里有10个人"
count(1) = "我给每人发个号码牌,数有10个牌"
count(现金) = "只有8个人带了现金"
count(会员卡) = "只有5个人有会员卡"
教室点名比喻
-- 教室里有50个座位

count(*) = "教室有50个座位"
count(1) = "我在每个座位放本书,最后数有50本"
count(学生) = "今天来了45个学生上课" (空座位不算)
七、总结与最佳实践
最终建议
统计总行数,一律用 count(*)

这是 SQL 标准写法
性能最优(MySQL有专门优化)
语义最明确
统计某列非 NULL 数量,用 count(列名)

这是它的本职工作
不要用它统计总行数
关于 count(1)

性能与 count(*) 一样
但不够"标准",像方言
建议统一用 count(*)
性能关键点

大表避免频繁 count
考虑使用缓存或汇总表
为 count(列名) 的列加索引
一张图看懂
count(*) -> 总数 -> 最快 -> 推荐使用
count(1) -> 总数 -> 一样快 -> 可用但不标准
count(主键) -> 总数 -> 次快 -> 主键非NULL时可用
count(索引列) -> 非NULL数 -> 较慢 -> 有索引时可用
count(普通列) -> 非NULL数 -> 最慢 -> 谨慎使用
记住口诀:"数总数,用星号;数非空,列名好;数字1,虽高效,不是标准别当宝"

如果你喜欢这篇文章,请点赞支持! 同时欢迎关注我的博客,获取更多精彩内容!

本文来自博客园,作者:佛祖让我来巡山,转载请注明原文链接:https://www.cnblogs.com/sun-10387834/p/19452600

站星网

一、快速结论(先看结论再看分析)方式 作用 效率 一句话总结count(*) 统计所有行数 最高 我是专业的!我为..

为您推荐

微服务/分布式 基础面试题

算法/协议说下paxos算法Paxos 有点类似 2PC,3PC,但比这两种算法更加完善。在很多多大厂都得到了工程实践,比如阿里的 OceanBase 的 分布式数据库, Google 的 chubby 分布式锁 。Paxos算法是什么? Paxos 算法是 ..

分享一个MySQL万能备份脚本

此脚本适用于 MySQL 各个生命周期的版本#!/bin/bash# mybackup.sh# 备份保留天数,建议保留三天days=7# 备份时间time=$(date +%Y%m%d%H%M%S)# 备份保存路径backup_dir=/opt/backup# 备份工具tool=mysqldump# 端口por..

MySQL 字符集、排序规则与查询关系详解

MySQL 查询是否区分大小写及重音敏感,取决于创建时指定的字符集(character set)和排序规则(collation)。(1)字符集(Character Set):规定可存储的字符,如 utf8、utf8mb4、latin1 等。(2)排序规则(Collat..

Mysql跨库操作

在 MySQL 中,操作多数据源(例如从库 A 和库 B)进行联查的情况,可以分为以下两种场景:A 库和 B 库在同一个 MySQL 实例当 A 库和 B 库在同一个 MySQL 实例下时,可以直接使用跨库联查查询。示例如下:SELECT A.co..

MySQL下200GB大表备份,利用传输表空间解决停服发版表备份问题

问题背景在停服发版更新时,需对 200GB 大表(约 200 亿行数据)进行快速备份以预防操作失误。因为曾经出现过有开发写的发版语句里,UPDATE语句的WHERE条件写错了,原本只需要更新几行数据,最终导致更新了半张表的..

服务器安装数据库MySQL8.0版本,打包导入到MySQL5.6失败的结局方式

最近数据库升级为mysql8.0,在使用过程中发现一些问题,首先mysql8.0有很多新特性,对服务器配置要求较高,所有就考虑把数据库版本切换到MySQL5.6,经过多出测试处理发现在8.0数据库打包的数据导入到5.6总是报错,或..

MySQL查询建表规范

因为之前一直再查找一些比较好的数据库规范,以方便在开发时连接 MySQL 进行查询/建表的时候,能根据规范来执行,达到提高 查询速度 / 执行 SQL 的性能 和提升 MySQL 的整体性能, 这里主要是存放一些比较好的一些数..

必须掌握的MySQL优化指南(2)

4|0表分区MySQL 在 5.1 版引入的分区是一种简单的水平拆分,用户需要在建表的时候加上分区参数,对应用是透明的无需修改代码。对用户来说,分区表是一个独立的逻辑表,但是底层由多个物理子表组成,实现分区的代码实..

mysql分表简单介绍

一、Mysql分表的原因1、当一张的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会停在那儿了。分表的目的就在于此,减小数据库的负担,缩短查询时间。2、mysql中有一种机制是表锁定..

MySQL创建用户与授权

一, 创建用户: 命令:CREATE USER'username'@'host' IDENTIFIED BY 'password'; 说明:username - 你将创建的用户名, host - 指定该用户在哪个主机上可以登陆,如果是本地用户可用localhost, ..

必须掌握的MySQL优化指南(1)

1.单表优化除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑、部署、运维的各种复杂度。一般以整型值为主的表在千万级以下,字符串为主的表在五百万以下是没有太大问题的。而事实上很多时..

2025年常见SQLServer数据库面试题

分享一些 2025年常见的 SQL Server 数据库面试题,涵盖基础知识、性能优化、高级查询、管理与运维等多个方面,适用于开发、DBA 及数据分析相关岗位的面试。1. SQL Server 的基本架构是什么?答案:SQL Server 的架构..

Mysql查询的一些操作(查表名,查字段名,查当月,查一周,查当天)

查询数据库中所有表名select table_name from information_schema.tables where table_schema='tools' and table_type='base table';查询指定数据库中指定表的所有字段名column_nameselect column_n..

MySQL查看、修改字符集及Collation

前言在使用MySQL的过程中,可能会出现初始设计使用的字符集或Collation不符合当前需求的情况。如使用utf8的表(MySQL中的utf8即utf8mb3)要支持emoji,而utf8mb3不支持emoji(emoji需要4个字节,而utf8mb3最长只支持..

MySQL SQL调优之索引

本篇记录MySQL的索引知识学习笔记,也方便自己以后查找复习一、索引的概念MySQL官方给出的索引定义:索引(Index)是帮助MySQL高效获取数据的数据结构。所以说索引就是排好序的快速查找数据结构二、索引分类MySQL的索..

mysql随机获取一条或者多条数据

语句一:select * from users order by rand() LIMIT 1MYSQL手册里面针对RAND()的提示大概意思就是,在 ORDER BY从句里面不能使用RAND()函数,因为这样会导致数据列被多次扫描,导致效率相当相当的低,效率不行,切..

Mysql子查询

子查询出现在select语句中的select语句,称为子查询或内查询。外部的select查询语句,称为主查询或外查询。子查询分类按结果集的行列数不同分为4种标量子查询(结果集只有一行一列)列子查询(结果集只有一列多行)..

MySQL批量插入的分析

1、背景我们在工作中基本都会碰到批量插入数据到DB的情况,这个时候我们就需要根据不同的情况选择不同的策略。只要了解sql,就应该知道,向table中插入数据的命令,至少有insert和replace这两种,使用哪一种命令,和..

Mysql查询一段时间内的数据

select * from wap_content where week(created_at) = week(now)如果你要严格要求是某一年的,那可以这样查询一天:select * from table where to_days(column_time) = to_days(now());select * from table where da..

MySQL 5.x和MySQL 8.x数据库的区别

MySQL 是开源关系型数据库的代表,广泛应用于不同规模的 Web 和企业应用中。从 MySQL 5.x 到 MySQL 8.x 的升级带来了大量功能改进和性能提升。为了帮助大家更直观地理解两者的区别,本文将通过详细介绍并结合实际的 ..

发表回复

返回顶部

微信分享

微信分享二维码

扫描二维码分享到微信或朋友圈

链接已复制
星辰影视-2025热门免费影视短剧平台熊猫影视-2025热门免费影视短剧平台番茄影视-2025热门免费影视短剧平台星光电影-2025热门免费影视短剧平台蜂鸟影院-2025热门免费影视短剧平台熊猫影视 - 全网高清免费影片聚合平台萝卜影院-2025热门电影电视剧免费在线播放-全站无广告高速播放下载樱花影院-2025热门免费影视短剧平台琪琪影视-2025热门免费影视短剧平台火影电影网-2025热门免费影视短剧平台悟空电影-2025热门免费影视短剧平台西瓜影院-2025热门免费影视短剧平台星空电影网-2025热门免费影视短剧平台好看电影网-2025热门免费影视短剧平台无忧影视网_高清影视在线观看分享平台_最新最全的免费影视短剧大全年钻网超清视界 - 全网高清免费短剧聚合平台极影公社-2025热门电影电视剧免费在线播放至尊影院-最新热门短剧免费电影网站_高清影视无弹窗极速播放星光电影-2025热门免费影视短剧平台河马影视-最新热门火爆的免费影视网站_高清影视夸克迅雷网盘下载叮当影视网-2025热门高清免费影视短剧分享平台70影视网 - 最新电影、电视剧、短剧、免费在线观看麻花影视网 - 高清免费聚合电影网西瓜影院-最新热门电影电视剧免费在线播放开心追剧网2048影视资源论坛-2048P.Com青青影视网-2025热门高清免费影视短剧分享平台八哥电影网_最新vip电影大全_热播电视剧_全网优质影视免费在线观看_老牌的免费在线影院_www.886958.com人人看电影-热播电视剧_2025年最新电影_人人影院高清在线免费观看天天影视网-高清免费电影、电视剧、短剧在线观看星辰影视-最新热门无广告的免费电影网站_高清影视无弹窗极速播放电影天堂爱看影院追剧达人U系列网盘资源橙子影视网天堂影视网天堂影视神马影院网大众影视网星辰影视网