在日常 SQL 开发中,统计数据是最常见的需求之一,而 COUNT 函数就是最核心的统计工具。
文章目录
-
- [一、COUNT 函数是什么?](#一、COUNT 函数是什么?)
-
- [1. 基本定义](#1. 基本定义)
- [二、COUNT 的三种常见用法](#二、COUNT 的三种常见用法)
-
- [1. COUNT(*)](#1. COUNT(*))
- [2. COUNT(1)](#2. COUNT(1))
- [3. COUNT(列名)](#3. COUNT(列名))
- [三、COUNT(*) vs COUNT(1) vs COUNT(列)](#三、COUNT(*) vs COUNT(1) vs COUNT(列))
- [四、COUNT 与 WHERE 条件](#四、COUNT 与 WHERE 条件)
-
- [1. 条件统计](#1. 条件统计)
- [2. 多条件统计](#2. 多条件统计)
- [3. 可以和IF结合使用](#3. 可以和IF结合使用)
- [五、COUNT + GROUP BY](#五、COUNT + GROUP BY)
-
- [1. 分组统计](#1. 分组统计)
- [2. 分组 + 条件](#2. 分组 + 条件)
- [六、COUNT + DISTINCT(去重统计)](#六、COUNT + DISTINCT(去重统计))
-
- [1. 基本用法](#1. 基本用法)
- [2. 多列去重(MySQL 支持)](#2. 多列去重(MySQL 支持))
- [七、COUNT 的执行原理](#七、COUNT 的执行原理)
-
- [1. InnoDB 表](#1. InnoDB 表)
- [2. MyISAM 表](#2. MyISAM 表)
- [3. 为什么 COUNT(*) 推荐?](#3. 为什么 COUNT(*) 推荐?)
- 八、性能优化建议
-
- [1. 优先使用 COUNT(*)](#1. 优先使用 COUNT(*))
- [2. 利用索引](#2. 利用索引)
- [3. 避免全表扫描](#3. 避免全表扫描)
- 参考

一、COUNT 函数是什么?
1. 基本定义
COUNT 是一个聚合函数,用于统计行数。
基本语法:
sql
COUNT(expression)
作用:
统计符合条件的记录数量。
二、COUNT 的三种常见用法
1. COUNT(*)
sql
SELECT COUNT(*) FROM user;
特点:
- 统计表中所有行
- 包含 NULL
- 最常用
👉 推荐使用
2. COUNT(1)
sql
SELECT COUNT(1) FROM user;
特点:
- 统计所有行
- 本质和 COUNT(*) 一样
👉 和 COUNT(*) 性能基本一致
3. COUNT(列名)
sql
SELECT COUNT(email) FROM user;
特点:
- 只统计该列 不为 NULL 的行
示例:
| id | |
|---|---|
| 1 | a@qq.com |
| 2 | NULL |
结果:
plain
COUNT(email) = 1
三、COUNT(*) vs COUNT(1) vs COUNT(列)
| 写法 | 是否统计 NULL | 含义 |
|---|---|---|
| COUNT(*) | 是 | 所有行 |
| COUNT(1) | 是 | 所有行 |
| COUNT(列名) | 否 | 非 NULL 行 |
一句话总结:
COUNT() = COUNT(1),COUNT(列) ≠ COUNT()
四、COUNT 与 WHERE 条件
1. 条件统计
sql
SELECT COUNT(*) FROM orders WHERE status = 'paid';
含义:
统计已支付订单数量。
2. 多条件统计
sql
SELECT COUNT(*)
FROM orders
WHERE amount > 100 AND status = 'paid';
3. 可以和IF结合使用
具体IF和IFNULL用法可参考MySQL IF 和 IFNULL 用法详解-CSDN博客

五、COUNT + GROUP BY
1. 分组统计
sql
SELECT status, COUNT(*)
FROM orders
GROUP BY status;
结果示例:
| status | count |
|---|---|
| paid | 10 |
| unpaid | 5 |
2. 分组 + 条件
sql
SELECT user_id, COUNT(*) AS order_count
FROM orders
GROUP BY user_id;
六、COUNT + DISTINCT(去重统计)
1. 基本用法
sql
SELECT COUNT(DISTINCT user_id) FROM orders;
含义:
统计不同用户数量。
2. 多列去重(MySQL 支持)
sql
SELECT COUNT(DISTINCT user_id, product_id)
FROM orders;
七、COUNT 的执行原理
1. InnoDB 表
- 不保存总行数
- 需要扫描数据
2. MyISAM 表
- 保存行数
- COUNT(*) 速度快
3. 为什么 COUNT(*) 推荐?
原因:
- 语义清晰
- 优化器会优化
- 可利用索引
八、性能优化建议
1. 优先使用 COUNT(*)
sql
SELECT COUNT(*) FROM table;
2. 利用索引
sql
SELECT COUNT(id) FROM user;
如果 id 是主键索引,会更快。
3. 避免全表扫描
大表建议:
- 使用缓存
- 使用统计表