COUNT(*)、COUNT(1)、COUNT(某一列)的区别是什么?哪个性能更好

一些特殊情况:

  • 有索引时:如果查询使用了索引,且查询的列在索引中,COUNT(某一列) 可能在某些情况下会比较快,因为数据库只需要扫描索引,而不需要扫描整个表。
  • 有 NULL 值时COUNT(某一列) 可能会因为 NULL 值的过滤而表现出与其他方法不同的性能特征。
  • WHERE 子句:无论是 COUNT(*)COUNT(1), 还是 COUNT(某一列),它们在有 WHERE 子句时,都会受限于条件的筛选,性能可能会受到查询条件的影响。

结论:

  • 对于大多数查询,推荐使用 COUNT(*),因为它通常是数据库最优化的选择。
  • COUNT(1) 性能与 COUNT(*) 基本相同,因此可以作为备选。
  • COUNT(某一列) 由于需要检查列值是否为 NULL,通常会稍微慢一些,特别是在数据中有大量 NULL 时。

一        介绍

1、COUNT(*):

这个表达式会计算表中的所有行,包括那些值为NULL的行。它不考虑列的选择,直接统计整个表的行数。

        MySQL官网[1]中有说明:InnoDB通过遍历最小的可用二级索引来处理SELECT COUNT(*)语句,除非索引或优化器提示优化器使用不同的索引。如果二级索引不存在,InnoDB通过扫描聚簇索引来处理SELECT COUNT(*)语句。

        为什么要采用遍历最小的可用二级索引,而不是直接选聚簇索引?

        因为二级索引不存储具体数据,相比聚簇索引占用空间小,遍历的I/O效率更高。

2、COUNT(1):

        这是一个优化过的计数方式,实际上并不计算任何列的值,而是把“1”作为一个常量来对待,统计的是满足条件的行数。这种方式避免了访问表的具体列,理论上可以提高效率,尤其是在列值可为空的情况下。

        MySQL官网[1]中有说明:InnoDB处理SELECT COUNT(*)和SELECT COUNT(1)操作的方式相同。

3、COUNT(某一列):

        这个表达式统计的是指定列中非NULL值的数量。如果该列有NULL值,那么这些行不会被计入总数中。

二        区别

1、数据处理范围:

        COUNT(*)包括了所有行,无论列值是否为NULL;COUNT(1)同样统计所有行,因为它计数的是恒定的1,不关心行数据的实际内容;而COUNT(某一列)只统计该列非NULL值的行数。

2、性能影响因素:

        由于COUNT(*)COUNT(1)不需要访问实际的数据行(特别是当索引可以覆盖查询需求时),它们的执行效率可能高于COUNT(某一列),特别是当该列含有大量NULL值时。

3、应用场景:

        如果你需要统计表的所有行数,包括那些具有NULL值的行,应使用COUNT(*)COUNT(1)。若你需要统计特定列的非NULL值数量,则应使用COUNT(某一列)

三        性能比较

        1、在MySQL中,COUNT(*)COUNT(1)的性能差异微乎其微,甚至可以认为是等价的。在MySQL官网中,明确指出InnoDB引擎中两语句性能一致[1]。原文如下:

InnoDB handles SELECT COUNT(*) and SELECT COUNT(1) operations in the same way. There is no performance difference.

        2、相比之下,COUNT(某一列)的性能取决于该列的数据分布,特别是NULL值的比例。如果该列包含大量NULL值,且查询优化器无法有效利用索引,那么它的执行效率可能会低于前两者。其中COUNT(主键)相比COUNT(普通列)的性能要好。

        3、实际性能还受到数据库索引、表结构、数据量、以及数据库管理系统具体实现等因素的影响。因此,在特定场景下,需进行实际测试。

四        结语

        总的来说,COUNT(*)COUNT(1)在统计全表行数时非常相似,且在多数情况下性能相当,推荐在不需要考虑特定列的NULL值时使用。而COUNT(某一列)则适用于需要精确统计某列非NULL值数量的场景。在考虑性能优化时,了解并利用数据库的特定优化特性和执行计划分析工具,可以帮助做出更合适的选择。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值