count(*),count(1),count(列名)执行原理、性能差异比较
2026/7/9 18:22:21 网站建设 项目流程

以下是 Oracle 中 COUNT函数的详细解析及对比,包含执行原理、性能差异和最佳实践。

一、执行原理


1. COUNT(expr) —— 统计非 NULL 值


作用:返回表达式中 不为 NULL​ 的行数。

SELECT COUNT(commission_pct) FROM employees;

•原理:遍历 commission_pct列,跳过所有 NULL值,只计算有值的行。

•注意:如果 expr涉及多列(如 COUNT(col1 + col2)),只要其中一列为 NULL,整个表达式结果即为 NULL,该行不计入统计。

2. COUNT(DISTINCT expr ) —— 统计唯一非 NULL 组合


作用:返回去重后、且 不为 NULL​ 的值的组合数量(Oracle 支持多列去重)。

-- 单列去重
SELECT COUNT(DISTINCT department_id) FROM employees;

-- 多列组合去重 (Oracle 特有)
SELECT COUNT(DISTINCT department_id || '-' || job_id) FROM
employees;
-- 或
SELECT COUNT(DISTINCT department_id, job_id) FROM employees; -- 12c+ 支持标准语法


•原理:先对 expr组合进行去重,再排除掉结果为 NULL的组合,最后计数。

•注意:如果 department_id和 job_id都为 NULL,该组合会被忽略;如果其中一个为 NULL,该组合依然参与去重计数。

3. COUNT(*) vs COUNT(1) —— 统计所有行


作用:两者都返回表中的总行数(包含 NULL 行)。

SELECT COUNT(*) FROM employees;
SELECT COUNT(1) FROM employees;

核心区别与执行原理

特性

COUNT(*)

COUNT(1)

含义

统计所有行数

对每一行计算常量1,然后统计行数

NULL 处理

包含 NULL 行

包含 NULL 行(因为1永远非 NULL)

Oracle 优化

最优。Oracle 对其进行了特殊优化,直接读取行数,无需计算表达式。

优化器通常会将其优化为COUNT(*),但早期版本或特定情况下可能略逊于*

索引利用

若表有主键或任意非空索引,可仅扫描索引(INDEX FAST FULL SCAN)。

同左,优化后行为一致。

结论COUNT(*)是 SQL 标准中统计行数的标准写法,也是 Oracle 官方推荐的最佳实践。

综合对比总结、

函数

是否计 NULL 行

是否去重

典型用途

COUNT()*​

统计全表或分组的总行数(最常用)

COUNT(1)

统计总行数(老习惯,建议改用*

COUNT(expr)

统计某列有值的数量(如统计有邮箱的员工数)

COUNT(DISTINCT expr)

统计某列不重复值的数量(如统计有多少个部门)

二、性能排序(通常情况下)

COUNT(*) ≈ COUNT(1)> COUNT(主键)> COUNT(普通列)

•原因:COUNT(*)不需要读取具体的列数据,只需找到一条存在的记录即可(利用索引最快)。COUNT(列)需要读取该列的数据块,I/O 成本更高。

三、最佳实践建议


1.统计行数:无条件使用 COUNT(*)。


2.统计某列非空值:使用 COUNT(column_name)。


3.统计唯一值:使用 COUNT(DISTINCT column_name)。

4.多列 DISTINCT 的陷阱
COUNT(DISTINCT col1, col2)统计的是 (col1, col2)组合的唯一性,而不是分别统计两列的唯一值。
-- 错误:想统计两列各自去重后的总数

SELECT COUNT(DISTINCT col1), COUNT(DISTINCT col2) FROM t;
-- 正确:必须分开写

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询