count(1) 和count(*)哪个高效?

1. count(1) and count(*)

当表的数据量大些时,对表作分析之后,使用count(1)还要比使用count(*)用时多了!

从执行计划来看,count(1)和count()的效果是一样的。但是在表做过分析之后,count(1)会比count()的用时少些(1w以内数据量),不过差不了多少。

如果count(1)是聚索引,id,那肯定是count(1)快。但是差的很小的。

因为count(),自动会优化指定到那一个字段。所以没必要去count(1),用count(),sql会帮你完成优化的 因此:count(1)和count(*)基本没有差别!

2. count(1) and count(字段)

两者的主要区别是

(1) count(1) 会统计表中的所有的记录数,包含字段为null 的记录。

(2) count(字段) 会统计该字段在表中出现的次数,忽略字段为null 的情况。即不统计字段为null 的记录。

3. count(*) 和 count(1)和count(列名)区别

执行效果上:

count(*)包括了所有的列,相当于行数,在统计结果的时候,不会忽略列值为NULL

count(1)包括了忽略所有列,用1代表代码行,在统计结果的时候,不会忽略列值为NULL

count(列名)只包括列名那一列,在统计结果的时候,会忽略列值为空(这里的空不是只空字符串或者0,而是表示null)的计数,即某个字段值为NULL时,不统计。

执行效率上:

列名为主键,count(列名)会比count(1)快

列名不为主键,count(1)会比count(列名)快

如果表多个列并且没有主键,则 count(1) 的执行效率优于 count(*)

如果有主键,则 select count(主键)的执行效率是最优的

如果表只有一个字段,则 select count(*)最优。

来自公众号Java技术驿站

<think>我们正在讨论SQL中的COUNT(*)函数。用户的问题是关于COUNT(*)中的星号(*)代表什么。 根据引用[3]的内容,在COUNT(*)中,星号(*)表示“计算行数”,它不指向任何特定的列,而是简单地计算表中的行数(或满足条件的行数)。 引用[3]还提到,在COUNT(*)中,星号(*)的含义是“数一下行数”,而如果使用列名(如COUNT(column)),则是计算该列非空值的行数。 因此,我们可以总结: - COUNT(*) 用于统计表中的记录行数,不论列值是否为NULL。 - 而COUNT(列名) 则统计该列非空值的行数。 另外,引用[1]引用[2]提供了关于COUNT(*)效率的讨论: - COUNT(1) COUNT(*) 在效率上非常接近,通常认为COUNT(*)会稍慢一点(因为需要将星号翻译成具体列名),但现代数据库已经优化,使得两者效率几乎相同。 - 性能排序大致为:COUNT(*)COUNT(1) > COUNT(主键id) > COUNT(普通索引列) > COUNT(未加索引列) 所以,在需要统计行数时,使用COUNT(*)是合适的,并且它直接表达了“统计所有行”的意图。 回答结构: 1. 直接解释COUNT(*)中星号的含义:代表所有行,不针对特定列。 2. 对比COUNT(*)COUNT(列名)的区别。 3. 简要提及性能(根据引用[2])。 4. 根据引用[3]说明在特定场景(如子查询)中,使用SELECT *代表一行也是合理的。 注意:用户的问题只要求理解COUNT(*)中的星号,所以重点放在解释星号的含义上。 最后,生成相关问题。</think>在 SQL 中,`COUNT(*)` 的星号(`*`)**不代表具体列,而是表示“计算表中的所有行数”**。它的核心作用特点如下: ### 一、星号的含义 1. **统计所有行** `COUNT(*)` 会计算查询结果中**所有行的数量**,无论这些行是否包含 `NULL` 值。 例如: ```sql -- 统计 Score 表的总行数(即所有学生选课记录) SELECT COUNT(*) FROM Score; ``` 2. **与 `COUNT(列名)` 的区别** - `COUNT(*)`:统计所有行,包括值为 `NULL` 的行。 - `COUNT(列名)`:仅统计该列**非 `NULL` 值**的行数。 例如: ```sql -- 统计 Score 表中 degree 列非空的行数 SELECT COUNT(degree) FROM Score; ``` ### 二、性能特点(参考引用[2]) `COUNT(*)` 的性能接近 `COUNT(1)`,两者都优于其他写法: ```plaintext COUNT(*)COUNT(1) > COUNT(主键) > COUNT(带索引列) > COUNT(无索引列) ``` 原因: - `COUNT(*)` `COUNT(1)` 直接扫描行数据,无需检查列值。 - `COUNT(列名)` 需额外检查列值是否为 `NULL`,效率略低[^2]。 ### 三、适用场景(参考引用[3]) 1. **需要精确统计行数时** 例如统计选修某课程的学生总数(包括成绩为 `NULL` 的记录): ```sql SELECT cno, COUNT(*) FROM Score GROUP BY cno; ``` 2. **子查询中表示“存在性”** 星号在子查询中仅表示“返回一行”,不涉及具体列: ```sql -- 检查是否存在选修某课程的学生 SELECT cno FROM Course WHERE EXISTS (SELECT * FROM Score WHERE Score.cno = Course.cno); ``` ### 四、常见误区 - ❌ 误区:`COUNT(*)` 效率低 事实:现代数据库已优化 `COUNT(*)`,其效率与 `COUNT(1)` 几乎相同[^1][^2]。 - ❌ 误区:`COUNT(*)` 统计所有列 事实:它只统计**行数**,与列内容无关[^3]。 > 总结:**`COUNT(*)` 中的星号是“所有行”的占位符**,优先用于需要精确统计行数的场景。需统计非空值时再用 `COUNT(列名)`。 --- ### 相关问题 1. 在 `WHERE` 子句中使用 `COUNT(*)` 会有什么问题?如何解决? 2. `COUNT(DISTINCT 列名)` `COUNT(列名)` 有何区别? 3. 大数据场景下如何优化 `COUNT(*)` 的查询效率? [^1]: `COUNT(1)` 在内部被视为固定值,性能与 `COUNT(*)` 接近,但 `COUNT(*)` 语义更明确。 [^2]: 扫描行数据比检查列值更高效,尤其当列无索引时差异更明显。 [^3]: `SELECT *` 在子查询中仅表示“返回一行”,不涉及具体列解析。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值