MySQL 使用 `WHERE` 子句时 `COUNT(*)`、`COUNT(1)` 和 `COUNT(column)` 的区别解析

文章目录

    • 1. COUNT() 函数的基本作用
    • 2. `COUNT(*)`、`COUNT(1)` 和 `COUNT(column)` 的详细对比
      • 2.1 `COUNT(*)` —— 统计所有符合条件的行
      • 2.2 `COUNT(1)` —— 统计所有符合条件的行
      • 2.3 `COUNT(column)` —— 统计某一列非 NULL 的记录数
    • 3. 性能对比
      • 3.1 `EXPLAIN` 分析
    • 4. 哪种方式更好?
      • 4.1 如果只是统计行数:
      • 4.2 统计某列的非 NULL 值:
      • 4.3 `COUNT(1)` 是否比 `COUNT(*)` 快?
    • 5. 结论
      • **最佳实践**

在 MySQL 查询优化过程中,COUNT(*)COUNT(1)COUNT(column) 这三种计数方式常常被混淆,尤其是在使用 WHERE 子句进行数据筛选时,它们的执行效率和结果可能有所不同。本文将深入解析这三者的区别,并结合 SQL 执行原理和优化策略,帮助开发者更高效地使用 COUNT() 函数。


1. COUNT() 函数的基本作用

COUNT() 是 SQL 语言中的聚合函数之一,主要用于统计符合条件的记录数。不同的 COUNT() 变体在处理 NULL 值和优化策略方面有所不同。

常见的 COUNT() 语法包括:

  • COUNT(*):统计表中所有符合条件的行(包括 NULL)。
  • COUNT(1):统计表中所有符合条件的行,与 COUNT(*) 类似。
  • COUNT(column):统计某一列中非 NULL 值的个数。

2. COUNT(*)COUNT(1)COUNT(column) 的详细对比

2.1 COUNT(*) —— 统计所有符合条件的行

COUNT(*) 计算所有符合 WHERE 条件的行数,不论这些行中的列是否包含 NULL 值。

示例:

SELECT COUNT(*) FROM users WHERE age > 18;

执行原理

  • MySQL 不会具体读取某一列的数据,而是统计符合 WHERE 条件的行数。
  • 在 InnoDB 存储引擎中,COUNT(*) 可以直接从索引中读取数据(如果合适的索引可用),性能较优。

适用场景

  • 需要统计表中所有符合条件的记录数,且不关心是否有 NULL 值时,COUNT(*) 是最佳选择。

2.2 COUNT(1) —— 统计所有符合条件的行

COUNT(1) 也是统计符合 WHERE 条件的行数,与 COUNT(*) 类似。

示例:

SELECT COUNT(1) FROM users WHERE age > 18;

执行原理

  • COUNT(1) 会在每一行返回 1,然后统计这些 1 的个数。
  • 在 MySQL 优化器看来,COUNT(1)COUNT(*) 的执行计划通常是相同的。
  • 在没有合适索引时,InnoDB 仍需进行全表扫描(或者索引扫描),不会因为 COUNT(1) 而有性能提升。

适用场景

  • COUNT(*) 作用几乎一致,但一般推荐使用 COUNT(*),因为 COUNT(*) 更符合 SQL 规范,并能适用于所有数据库系统。

2.3 COUNT(column) —— 统计某一列非 NULL 的记录数

COUNT(column) 仅统计某一列中非 NULL 的记录数,而不会统计 NULL 值。

示例:

SELECT COUNT(email) FROM users WHERE age > 18;

执行原理

  • 只有 email 列不为 NULL 的行才会被计入统计。
  • MySQL 需要读取 email 列的数据,以判断其是否为 NULL,因此比 COUNT(*)COUNT(1) 可能稍慢(如果 email 列没有索引)。

适用场景

  • 需要排除 NULL 值时,比如统计已填写 email 地址的用户数量。

3. 性能对比

为了对比 COUNT(*)COUNT(1)COUNT(column) 的性能,我们进行如下实验:

假设有一个 users 表,其中 id 为主键,email 为可能包含 NULL 的列,数据如下:

idnameageemail
1张三20zhangsan@a.com
2李四25NULL
3王五22wangwu@b.com
4赵六19NULL

测试 SQL 及其返回结果如下:

SELECT COUNT(*) FROM users WHERE age > 18;  -- 结果:3
SELECT COUNT(1) FROM users WHERE age > 18;  -- 结果:3
SELECT COUNT(email) FROM users WHERE age > 18;  -- 结果:2 (NULL 值被排除)

3.1 EXPLAIN 分析

如果 users 表的 email 没有索引,那么 COUNT(email) 需要扫描 email 列的数据,会比 COUNT(*) 略慢。

对于 COUNT(*)COUNT(1),InnoDB 通常会直接使用主键索引进行优化,因此在大多数情况下,两者性能相同。

示例 EXPLAIN 结果:

EXPLAIN SELECT COUNT(*) FROM users WHERE age > 18;
idselect_typetabletypepossible_keyskeyrowsExtra
1SIMPLEusersindexNULLPRIMARY3Using index

Using index 表示 MySQL 直接利用索引进行优化,而无需扫描所有数据。


4. 哪种方式更好?

4.1 如果只是统计行数:

  • 推荐使用 COUNT(*),因为它可以利用索引优化,并且与数据库无关,通用性更强。

4.2 统计某列的非 NULL 值:

  • 使用 COUNT(column),但要注意 NULL 值不会被计入。

4.3 COUNT(1) 是否比 COUNT(*) 快?

  • 在 MySQL 5.7 及以上版本,COUNT(1)COUNT(*) 在优化器层面已经没有明显性能差异,因此一般推荐使用 COUNT(*),更符合 SQL 规范。

5. 结论

计数方式作用处理 NULL性能优化
COUNT(*)统计符合 WHERE 条件的总行数统计所有行(包括 NULL)最优(可利用索引)
COUNT(1)统计符合 WHERE 条件的总行数统计所有行(包括 NULL)COUNT(*) 类似
COUNT(column)统计某列非 NULL 的行数只统计非 NULL 值可能稍慢(依赖索引情况)

最佳实践

  • 默认使用 COUNT(*),它性能最优且兼容性强。
  • COUNT(column) 适用于特定需求,如统计非 NULL 值个数。
  • 避免误解 COUNT(1) 更快的说法,在现代 MySQL 中它与 COUNT(*) 无本质区别。

希望这篇文章能帮助你更深入理解 MySQL 计数函数的优化策略,提高查询性能!🚀

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/70959.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

将DeepSeek接入vscode的N种方法

接入deepseek方法一:cline 步骤1:安装 Visual Studio Code 后,左侧导航栏上点击扩展。 步骤2:搜索 cline,找到插件后点击安装。 步骤3:在大模型下拉菜单中找到deep seek,然后下面的输入框输入你在deepseek申请的api key,就可以用了 让deepseek给我写了一首关于天气的…

AndroidManifest.xml文件的作用

AndroidManifest.xml文件在Android应用程序中扮演着至关重要的角色。它是应用程序的全局配置文件,提供了关于应用程序的所有必要信息,这些信息对于Android系统来说是至关重要的,因为它决定了应用程序的运行方式和权限要求,确保了应…

Mac本地部署Deep Seek R1

Mac本地部署Deep Seek R1 1.安装本地部署大型语言模型的工具 ollama 官网:https://ollama.com/ 2.下载Deepseek R1模型 网址:https://ollama.com/library/deepseek-r1 根据电脑配置,选择模型。 我的电脑:Mac M3 24G内存。 这…

React进阶之前端业务Hooks库(五)

前端业务Hooks库 Hooks原理useStateuseEffect上述问题useState,useEffect 复用的能力练习:怎样实现一套React过程中的hooks状态 & 副作用Hooks原理 不能在循环中、条件判断、子函数中调用,只能在函数最外层去调用useEffect 中,deps 为空,执行一次useState 使用: imp…

从像素到光线:现代Shader开发的范式演进与性能优化实践

引言 在实时图形渲染领域,Shader作为GPU程序的核心载体,其开发范式已从早期的固定功能管线演进为高度可编程的计算单元。本文通过解析关键技术案例,结合现代图形API(如Vulkan、Metal)的特性,深入探讨Shade…

(七)消息队列-Kafka 序列化avro(传递)

(七)消息队列-Kafka 序列化avro(传递) 客从远方来,遗我双鲤鱼。呼儿烹鲤鱼,中有尺素书。 ——佚名《饮马长城窟行》 本文已同步CSDN、掘金平台、知乎等多个平台,图片依然保持最初发布的水印&…

PXE批量网络装机与Kickstart自动化安装工具

目录 一、系统装机的原理 1.1、系统装机方式 1.2、系统安装过程 二、PXE批量网络装机 2.1、PXE实现原理 2.2、搭建PXE实际案例 2.2.1、安装必要软件 2.2.2、搭建DHCP服务器 2.2.3、搭建TFTP服务器 2.2.4、挂载镜像并拷贝引导文件到tftp服务启动引导文件夹下 2.2.5、编…

【全栈开发】从0开始搭建一个图书管理系统【一】框架搭建

【全栈开发】从0开始搭建一个图书管理系统【一】框架搭建 前言 现在流行降本增笑,也就是不但每个人都要有事干不能闲着,更重要的是每个人都要通过报功的方式做到平日的各项工作异常饱和,实现1.5人的支出干2人的活计。单纯的数据库开发【肤浅…

部署Flink1.20.1

1、设置环境变量 export JAVA_HOME/cluster/jdk export CLASSPATH.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jarp #export HIVE_HOME/cluster/hive export MYSQL_HOME/cluster/mysql export HADOOP_HOME/cluster/hadoop3 export HADOOP_CONF_DIR$HADOOP_HOME/etc/hadoop …

【超详细】神经网络的可视化解释

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

深入了解 Python 中的 MRO(方法解析顺序)

文章目录 深入了解 Python 中的 MRO(方法解析顺序)什么是 MRO?如何计算 MRO?C3 算法的合并规则C3 算法的合并步骤示例:合并过程解析 MRO 解析失败的场景使用 mro() 方法查看 MRO示例 1:基本用法 菱形继承与…

数字化赋能:制造业如何突破低效生产的瓶颈?

随着全球经济的快速发展与市场需求的变化,制造业面临着前所未有的压力与挑战。生产效率、资源管理、品质控制、成本控制等方面的问题日益突出,尤其是低效生产成为了许多制造企业亟待解决的瓶颈。在这种背景下,数字化转型成为提升制造业效率的…

Element-Plus,使用 El-form中 的 scroll-to-error 没有效果问题记录

因业务需要表单组件中嵌套着表格列表,内容比较多; 所以需要表单校验不通过时,自动定位到不通过的节点; 但发现这个像是没有起到效果一样,后面就是排查的思路了: 容器高度问题:如果表单容器的高度…

基于Javase的停车场收费管理系统

基于Javase的停车场收费管理系统 停车场管理系统开发文档 项目概述 1.1 项目背景 随着现代化城市的不断发展,车辆数量不断增加,停车难问题也日益突出。为了更好地管理停车场资 源,提升停车效率,需要一个基于Java SE的停车场管理…

网络协议 HTTP、HTTPS、HTTP/1.1、HTTP/2 对比分析

1. 基本定义 HTTP(HyperText Transfer Protocol) 应用层协议,用于客户端与服务器之间的数据传输(默认端口 80)。 HTTP/1.0:早期版本,每个请求需单独建立 TCP 连接,效率低。HTTP/1.1&…

DeepSeek掘金——调用DeepSeek API接口 实现智能数据挖掘与分析

调用DeepSeek API接口:实现智能数据挖掘与分析 在当今数据驱动的时代,企业和开发者越来越依赖高效的数据挖掘与分析工具来获取有价值的洞察。DeepSeek作为一款先进的智能数据挖掘平台,提供了强大的API接口,帮助用户轻松集成其功能到自己的应用中。本文将详细介绍如何调用D…

LabVIEW同步数据采集功能

VI通过使用数据采集(DAQ)硬件系统,进行多通道同步采集,实时获取模拟信号数据。它利用外部时钟信号触发数据采集,支持连续采样模式,并将采集到的数据实时显示在波形图上,方便用户进行数据监控和分…

SpringDataJPA使用deleteAllInBatch方法逻辑删除失效

概述 在使用Spring Boot JPA时,执行批量删除操作时,遇到逻辑删除失效的问题。具体而言,当使用deleteAllInBatch方法时,数据会被物理删除,而不是进行逻辑删除;但是当使用deleteAll时,逻辑删除操…

【Docker】使用Docker搭建-MySQL数据库服务

零、更换Docker镜像源 因为国内现在封锁了Docker默认拉取镜像的站点(DockerHub),而且国内大部分Docker镜像站已全部下线,导致现在很多朋友在拉取镜像的时候会出现无法拉取的现象,这时候就需要进行更换Docker镜像源。 可…

人类驾驶的人脑两种判断模式(反射和预判)-->自动驾驶两种AI模式

一种模式是直觉模式,判断基于条件反射,视觉感知 触发到 直接条件反射(从经历中沉淀形成的神经信息闭环),类似现在自动驾驶技术的传统AI模式;另一种是图式推理模式,判断是基于预判,人…