COUNT(expr) 函数学习

本文详细介绍了SQL中的COUNT函数的三种使用方式及其效率对比。包括COUNT(*)、COUNT(1)及COUNT(字段)的区别与应用场景,同时深入探讨了MySQL数据库对COUNT(*)进行的优化措施。

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

COUNT(expr) 函数使用总共分为三种情况:

名称执行过程
COUNT(*)在执行时返回检索到的行数计数,不管这些行是否包含 NULL 值
COUNT(1)在执行时遇到了行的时候为恒真表达式,在统计结果时和 COUNT(*) 一样统计所有行
COUNT(字段)在执行时全表扫描该字段,然后判断拿到的字段的值是不是为 NULL,不为 NULL 则累加
总结:
  • COUNT(1) 和 COUNT(*) 表示的是直接查询符合条件的数据库表的行数
  • COUNT(字段)表示的是查询符合条件的列的值,并判断不为NULL的行数的累计,效率会低
  • 除了查询得到结果集有区别之外,相比COUNT(1) 和 COUNT(字段)来讲,COUNT(*)是 SQL92 定义的标准统计数的语法,是官方提供的标准方案,基于此,MySQL数据库对他进行过很多优化

注:SQL92 是数据库的一个 ANSI/ISO 标准。它定义了一种语言(SQL)以及数据库的行为(事务、隔离级别等)

使用建议:
  • 从效率层面说 COUNT(*) ≈ COUNT(1) > COUNT(字段)
  • 因为 COUNT(*) 是 SQL92 定义的标准统计数的语法,所以推荐使用 COUNT(*)
  • 判断数据在否,可使用 SELECT COUNT(*) FROM ...... LIMT 1 代替 SELECT COUNT(*) ......

注:规避了 SQL 使用 COUNT 表达式扫表的操作,而是改用 SELECT 1 ... LIMIT 1,数据库查询时遇到一条就返回,不会再继续查找和执行,如果存在传输回一条结果为 1 的数据 ,否则为 NULL,业务代码中直接判断是否非空即可


拓展:MySQL 数据库对 COUNT(*) 做了哪些优化
  • MyISAM | 不支持事务,MyISAM中的锁是表级锁

    因为MyISAM的锁是表级锁,所以同一张表上面的操作是串行执行的,MyISAM把表的总行数单独记录下来,如果只是使用COUNT(*)对表进行查询的时候,可以直接返回这个记录的数值就可以了。

  • InnoDB | 支持事务,其中大部分操作都是行级锁

    因为表的行数可能会被并发修改,缓存记录下来的总行数就不准确了。
    在InnoDB中,使用 COUNT(*) 查询行数的时候,不需要进行扫表,只要获取记录行数而已。所以官方在针对 InnoDB 的 SELECT COUNT(*) FROM 语句执行过程,会自动选择一个成本较低的索引进行的话,这样就可以大大节省时间。
    InnoDB 中索引分为 聚簇索引(主键索引)非聚簇索引(非主键索引),聚簇索引的叶子节点中保存的是整行记录,而非聚簇索引的叶子节点中保存的是该行记录的主键的值,非聚簇索引要比聚簇索引小很多,MySQL 会优先选择最小的非聚簇索引来扫表,这样可以保证 COUNT(*) 的最优效率。当查询语句中包含 WHERE 以及 GROUP BY 条件,会有一些其他的因素影响,所以要综合考虑。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值