count(*),count(1),count(列名)执行原理、性能差异比较

📅 2026/7/9 18:22:32
count(*),count(1),count(列名)执行原理、性能差异比较
以下是 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) FROMemployees;-- 或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永远非 NULLOracle 优化​最优。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;-- 正确必须分开写