mysql如何使用count函数_mysql记录计数查询示例

来源:这里教程网 时间:2026-02-28 20:48:26 作者:

count(*) 和 count(字段) 的行为差异

直接用

count(*)
统计行数最安全,它不关心字段是否为 NULL;而
count(列名)
会跳过该列值为
NULL
的所有行。比如用户表里有 100 条记录,但
email
字段有 12 个是
NULL
,那么
count(email)
返回 88,
count(*)
才是 100。

常见误用场景:想查“有多少用户填了手机号”,却写了

count(*)
,结果得到总注册数而非有效填写数 —— 这时必须明确用
count(phone)
(前提是
phone
允许为
NULL
)。

带 WHERE 条件的 count 查询写法

统计不是简单套函数,条件过滤必须写在

WHERE
子句里,不能靠
HAVING
(除非已分组)。例如查“2024 年注册的活跃用户数”:

SELECT COUNT(*) FROM users 
WHERE status = 'active' 
  AND created_at >= '2024-01-01';

注意点:

WHERE
在聚合前过滤,性能好;
HAVING
是聚合后筛,开销大且逻辑易错
时间字段比较要确认类型:若
created_at
DATETIME
,用字符串比较没问题;若是
TIMESTAMP
且有时区,可能需用
FROM_UNIXTIME()
或显式转换
避免在
WHERE
中对字段用函数(如
YEAR(created_at) = 2024
),会导致索引失效

count 配合 GROUP BY 做分组统计

需要按类别看数量时,

GROUP BY
是必选项,漏掉会只返回一行汇总结果。例如统计各城市用户数:

SELECT city, COUNT(*) AS user_count 
FROM users 
WHERE city IS NOT NULL 
GROUP BY city 
ORDER BY user_count DESC;

关键细节:

GROUP BY
列必须出现在
SELECT
中(除非用 MySQL 5.7+ 的
ONLY_FULL_GROUP_BY
关闭模式)
如果
city
有空值,
GROUP BY
会把所有
NULL
归为一组,通常要加
WHERE city IS NOT NULL
过滤
别名(如
user_count
)不能在
WHERE
中引用,但可在
HAVING
中用,比如加
HAVING user_count > 100

count 查询慢?先看执行计划和索引

COUNT(*)
在 InnoDB 表上并不总是全表扫描 —— 如果有合适索引且无
WHERE
条件,MySQL 可能用二级索引的叶子节点行数估算(但不绝对,尤其大表)。真正拖慢的往往是:

没加
WHERE
却查大表的
COUNT(*)
:InnoDB 必须遍历聚簇索引或某二级索引,数据量越大越慢
WHERE
条件没走索引:比如
WHERE CONCAT(name, '') = 'John'
WHERE DATE(create_time) = '2024-01-01'
用了
JOIN
后再
COUNT(*)
:可能产生笛卡尔积,行数暴增

排查方法:在语句前加

EXPLAIN
,重点看
type
是否为
index
range
rows
是否远小于表总行数。

复杂点在于:有些业务场景下,精确实时计数本身就不该由数据库承担 —— 比如百万级商品的销量总数,更适合用 Redis 计数器或异步更新汇总表。

相关推荐