count(1) AND count(*) 对比

本文通过实验对比了MySQL数据库中Count(*)与Count(1)的执行效率,并探讨了不同条件下的表现差异及背后的原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

相信很多小伙伴都想知道count(1) 和 count(*) 的速度问题 ,今天我给大家做一下测试。我这里测试的是MySql数据库

声明:测试之前

我数据库表里面有100万条数据。我们先来测试count(*)

可以看出,count(*) 用时间差不多15秒,下面我们看一下count(1)

 

看到这我知道很多小伙伴还是找不到心里的答案,上面他可有一些客观原因。都是电脑重启后测试的,电脑重启后。肯定会加载启动项。所以效率上肯定有所差异。然而我再重启电脑后测试的select count(1) from test 第一个用时

 

34秒。所以上面做一个了解。下面我们看看电脑运行处于平稳状态下的对比,请看第一个对比count(*) 5.49 count(1) 5.11

别着急。俗话都是三局两胜,五局三胜,我们看第二次count(*) 4.86 count(1) 5.64

再看第三次count(*) 4.92 count(1) 4.39

第一个总结:count(*)  count(1)  在没条件的情况下两者没有什么区别

然在上面是没有条件的。下面是有条件的

我对比了两次,可以看出count(*) 快于count(1),  下面来解释一下

count(1) 和count(*) 对比

如果你数据库没有主键count(1) 比count(*) 快,如果有主键主键作为条件count() 那么count(1) 比count(*) 快。

如果表里面只有一个字段那么是count(*)最快

count 解释

count(*) 返回表中所有存在行的总数包括null,然而count(1) 返回的是去除null以外的所有行的总数。有默认值的也会被记录

这下就对count 有一定的了解的把。可以动手测试一下

最后总结三条经验,(这个也是好久之前在网上看到的,不过本人亲自测试过)

1.任何情况下select count(*) from table 最优选择

2.减少select count(*) from table where condition = ? 这样的查询

3.杜绝select count(colunm) from table

 

好了到此就介绍完了,以上是自己的总结。哪里有不足。欢迎在下方留言,谢谢!

 

<think>我们正在讨论SQL查询中COUNT(*)的*的含义。用户引用了一些示例,但核心问题是COUNT(*)中的*代表什么。 根据之前的解释,COUNT(*)中的*表示“所有行”,即统计表中的所有行数,考虑任何列的值,包括NULL值。 用户现在给出的具体查询是: SELECT cno, AVG(degree) AS average_degree FROM Score GROUP BY cno HAVING cno LIKE '3%' AND COUNT(*) >= 5 在这个查询中,COUNT(*)出现在HAVING子句中,用于过滤分组结果。 解释: 1. GROUP BY cno:将Score表按照课程号(cno)分组。 2. HAVING子句:对分组后的结果进行过滤。 条件1:cno LIKE '3%' —— 课程号以3开头。 条件2:COUNT(*) >= 5 —— 该分组中的行数(即选修该课程的学生人数)大于等于5。 这里COUNT(*)的作用是计算每个课程分组(即每个cno)对应的行数(即学生选课记录数)。 注意:COUNT(*)COUNT(列名)的区别: - COUNT(*):统计分组内的所有行数,无论行中是否有NULL值。 - COUNT(degree):如果使用这个,则只会统计degree列非空的行数。 在这个上下文中,我们关心的是选修该课程的学生人数(即行数),所以使用COUNT(*)是合适的,因为它会包括所有选课记录,即使某条记录的degree是NULL(比如学生缺考,成绩未录入)。 因此,在这个查询中,COUNT(*)的*代表每个分组(每个课程)中的所有行(所有选课记录)。 引用说明:用户引用的[1]中有一个类似的查询,其中使用了COUNT(*)来统计学生人数,并作为分组条件。这与当前查询一致。 总结:在SQL中,COUNT(*)的*是一个特殊符号,表示“所有行”,用于统计行数。在分组查询中,它统计每个分组中的行数。 相关问题: 1. 在分组查询中,HAVING子句WHERE子句有什么区别? 2. 如果使用COUNT(degree)代替COUNT(*),会有什么同? 3. 在HAVING子句中同时使用分组列的条件聚合函数的条件,执行顺序是怎样的?</think>在 SQL 查询语句 `SELECT cno, AVG(degree) AS average_degree FROM Score GROUP BY cno HAVING cno LIKE '3%' AND COUNT(*) >= 5` 中,`COUNT(*)` 的星号(`*`)表示**统计分组中的总行数**,具体含义如下: ### 一、`COUNT(*)` 的含义 1. **统计所有行** `COUNT(*)` 会计算每个 `cno`(课程号)分组下的**所有记录行数**,无论这些行中的 `degree`(成绩)是否为 `NULL` 值[^1]。 2. **与列无关** 星号指向任何具体列(如 `cno` 或 `degree`),而是表示“**该分组的所有行**”。例如: - 若课程 `3-105` 有 5 条成绩记录(包括 `degree` 为 `NULL` 的记录),`COUNT(*)` 返回 5 - 若使用 `COUNT(degree)`,则只统计 `degree` 非 `NULL` 的行(可能少于 5) ### 二、在查询中的具体作用 在您的查询中: ```sql SELECT cno, AVG(degree) AS average_degree FROM Score GROUP BY cno HAVING cno LIKE '3%' AND COUNT(*) >= 5 ``` - `COUNT(*) >= 5` 表示:**只保留选修人数 ≥ 5 的课程分组** - 它与 `cno LIKE '3%'`(课程号以 3 开头)共同作为分组过滤条件 ### 三、与 `COUNT(列名)` 的对比 | 场景 | `COUNT(*)` | `COUNT(degree)` | |---------------------|--------------------------------|-------------------------------| | 统计选修人数 | ✅ 准确(包含所有记录) | ❌ 可能漏掉 `degree=NULL` 的记录 | | 统计有效成绩数量 | ❌ 适用 | ✅ 仅统计非空成绩 | | 查询性能 | ⚡️ 更优(直接扫描行)[^2] | ⚠️ 需检查列值 | ### 四、为什么这里必须用 `COUNT(*)` 1. **需求匹配** 您的查询目标是统计“**选修人数**”(即行数),而非“有效成绩数量”[^1]。 → 必须用 `COUNT(*)` 确保包含所有选课记录。 2. **语义明确性** `COUNT(*)` 明确表示“统计行数”,而 `COUNT(degree)` 表示“统计非空成绩数”[^3]。 > **结论**:此处的 `*` 是“所有行”的占位符,用于精确统计每个课程分组的总记录数,确保 `HAVING` 条件能正确过滤选修人数足 5 人的课程。 --- ### 相关问题 1. 如果使用 `COUNT(degree)` 替代 `COUNT(*)`,查询结果会有什么变化? 2. 在 `HAVING` 子句中,`COUNT(*)` `WHERE` 子句的过滤条件执行顺序是什么? 3. 如何优化包含 `COUNT(*)` 的分组查询性能? [^1]: 如引用[1]所示,`COUNT(*)` 用于统计选修人数(行数),而非具体列值。 [^2]: 引用[2]证明 `COUNT(*)` 性能优于列统计,尤其在分组场景。 [^3]: 引用[3]强调 `COUNT(*)` 与列值统计的本质差异。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值