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

2次阅读

count(*)统计所有行,安全可靠;count(字段)跳过NULL值,适用于统计非空数量;带WHERE的条件过滤应在聚合前进行,避免索引失效和性能问题。

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

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_atdateTIME,用字符串比较没问题;若是 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 是否为 indexrangerows 是否远小于表总行数。

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

text=ZqhQzanResources