关于SQL中count的效率

本文探讨了COUNT(*)与COUNT(COL)在不同情况下的性能差异,特别是在没有WHERE限制与存在WHERE条件时的不同表现。文章通过实验数据说明,在实际应用中COUNT(*)通常更快,并给出了优化建议。

COUNT(*)与COUNT(COL)
网上搜索了下,发现各种说法都有:
比如认为COUNT(COL)比COUNT(*)快的;
认为COUNT(*)比COUNT(COL)快的;
还有朋友很搞笑的说到这个其实是看人品的。

不加WHERE限制条件的情况下,COUNT(*)与COUNT(COL)基本可以认为是等价的;
但是在有WHERE限制条件的情况下,COUNT(*)会比COUNT(COL)快非常多;

具体的数据参考如下:

 

mysql> SELECT COUNT(*) FROM cdb_posts where fid = 604;
+————+
| COUNT(fid) |
+————+
| 79000 |
+————+
1 row in set (0.03 sec)

mysql> SELECT COUNT(tid) FROM cdb_posts where fid = 604;
+————+
| COUNT(tid) |
+————+
| 79000 |
+————+
1 row in set (0.33 sec)

mysql> SELECT COUNT(pid) FROM cdb_posts where fid = 604;
+————+
| COUNT(pid) |
+————+
| 79000 |
+————+
1 row in set (0.33 sec)

COUNT(*)通常是对主键进行索引扫描,而COUNT(COL)就不一定了,另外前者是统计表中的所有符合的纪录总数,而后者是计算表中所有符合的COL的纪录数。还有有区别的。

 

COUNT时的WHERE

简单说下,就是COUNT的时候,如果没有WHERE限制的话,MySQL直接返回保存有总的行数
而在有WHERE限制的情况下,总是需要对MySQL进行全表遍历。

优化总结
1.任何情况下SELECT COUNT(*) FROM tablename是最优选择;
2.尽量减少SELECT COUNT(*) FROM tablename WHERE COL = ‘value’ 这种查询;
3.杜绝SELECT COUNT(COL) FROM tablename WHERE COL2 = ‘value’ 的出现。

### SQL COUNT 函数用法详解 COUNTSQL 中用于统计满足特定条件的记录数的一个聚合函数。它能够统计表中的总行数、某一列中非 NULL 值的数量以及去重后的数量。 #### 1. 统计所有行(包括 NULL) 当需要统计表中所有的行时,可以使用 `COUNT(*)` 或者 `COUNT(1)`。这两种方法在现代数据库中经过优化后性能基本一致[^2]。 ```sql -- 使用 COUNT(*) SELECT COUNT(*) AS total_rows FROM employees; -- 使用 COUNT(1) SELECT COUNT(1) AS total_rows FROM employees; ``` #### 2. 统计指定列中非 NULL 值的数量 如果只想统计某个字段中有实际数据(即非 NULL)的行数,则可使用 `COUNT(column_name)`。 ```sql SELECT COUNT(salary) AS non_null_salaries FROM employees; ``` 此查询会返回 salary 字段中非 NULL 的记录总数[^2]。 #### 3. 统计唯一值的数量 通过加上 DISTINCT 关键字,可以让 COUNT 只计算不同(unique)的值。 ```sql SELECT COUNT(DISTINCT department_id) AS unique_departments FROM employees; ``` 这条语句将给出部门 ID 列里独一无二条目的数目[^1]。 #### 4. 条件下的计数 有时可能希望基于某些逻辑来决定哪些行应该被计入最终的结果集之中。这可以通过几种方式实现: - **OR NULL 方法** 利用布尔表达式的特性,在不符合条件的情况下自动视为 NULL 并排除在外。 ```sql SELECT COUNT(age > 30 OR NULL) AS over_thirty_years_old FROM users; ``` - **IF 函数** 对于支持 IF 结构的语言版本来说更为直观明了。 ```sql SELECT COUNT(IF(age > 30, TRUE, NULL)) AS over_thirty_years_old FROM users; ``` - **CASE WHEN 构造** 这是最通用也是推荐的方式之一,因为它兼容性强且易于理解。 ```sql SELECT COUNT(CASE WHEN age > 30 THEN 1 END) AS over_thirty_years_old FROM users; ``` 以上三种形式均能达到同样的效果——筛选年龄大于三十岁的用户并对其人数加以汇总[^1]。 #### 5. 配合 GROUP BY 进行分组统计 还可以联合其他子句如 GROUP BY 实现更复杂的数据分析需求。 ```sql SELECT department_id, COUNT(*) AS dept_count FROM employees GROUP BY department_id; ``` 该例子展示了如何按照部门编号分类员工,并分别得出各个类别下的人头数[^2]。 ### 注意事项 尽管 COUNT 能够很好地完成各种类型的计数任务,但在设计查询的时候仍需注意效率考量。比如尽量避免不必要的全表扫描;合理运用索引来加速检索过程等等。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值