SQL中count(1)、count(*) 与 count(列名)的区别详细解释

 更新时间:2024年08月15日 08:31:40   作者:灰_灰丶灰  
count(1)和count(*)是SQL中用于统计行数的两种常见方式,它们的区别在于统计的对象不同,下面这篇文章主要给大家介绍了关于SQL中count(1)、count(*) 与 count(列名)区别的相关资料,需要的朋友可以参考下

前言

在 SQL 中,COUNT 函数用于计算查询结果集中的行数。COUNT(1)COUNT(*) 和 COUNT(列名) 都可以用来统计行数,但它们在实现细节和使用场景上有一些区别。以下是详细的解释:

1. COUNT(1)

  • 定义COUNT(1) 计算查询结果集中的行数。
  • 实现: 在执行过程中,COUNT(1) 会将 1 作为一个非空的常量值,并对每一行进行计数。
  • 效率: 现代的 SQL 优化器通常会将 COUNT(1) 和 COUNT(*) 优化为相同的执行计划,因此性能基本相同。
  • 用途: 适用于计算总行数,与 COUNT(*) 无区别。
SELECT COUNT(1) FROM employees;

2. COUNT(*)

  • 定义COUNT(*) 计算查询结果集中的总行数,包括所有列,不会忽略任何行,即使某些列包含 NULL
  • 实现: SQL 优化器会对 COUNT(*) 进行优化,将其转换为统计行数的操作。
  • 效率: 通常是最常用和推荐的方式,因为其语义明确且优化器能够很好地处理。
  • 用途: 适用于计算总行数,性能通常优于 COUNT(列名)
SELECT COUNT(*) FROM employees;

3. COUNT(列名)

  • 定义COUNT(列名) 计算查询结果集中某一列非 NULL 值的行数。
  • 实现: 只有当指定列的值不为 NULL 时,该行才会被计入结果。
  • 效率: 由于需要检查每行中的特定列是否为 NULL,性能可能略低于 COUNT(*) 和 COUNT(1)
  • 用途: 适用于计算某一特定列中非 NULL 值的数量。
SELECT COUNT(department_id) FROM employees;

示例代码

下面是一个使用 JDBC 示例代码,展示如何使用 COUNT(1)COUNT(*) 和 COUNT(列名)

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class CountExample {
    private static final String JDBC_URL = "jdbc:mysql://localhost:3306/yourdatabase";
    private static final String JDBC_USER = "yourusername";
    private static final String JDBC_PASSWORD = "yourpassword";

    public static void main(String[] args) {
        try (Connection conn = DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASSWORD);
             Statement stmt = conn.createStatement()) {

            // 使用 COUNT(1)
            String count1SQL = "SELECT COUNT(1) AS total FROM employees";
            ResultSet rs1 = stmt.executeQuery(count1SQL);
            if (rs1.next()) {
                int total1 = rs1.getInt("total");
                System.out.println("Total rows (COUNT(1)): " + total1);
            }

            // 使用 COUNT(*)
            String countAllSQL = "SELECT COUNT(*) AS total FROM employees";
            ResultSet rsAll = stmt.executeQuery(countAllSQL);
            if (rsAll.next()) {
                int totalAll = rsAll.getInt("total");
                System.out.println("Total rows (COUNT(*)): " + totalAll);
            }

            // 使用 COUNT(column)
            String countColumnSQL = "SELECT COUNT(department_id) AS total FROM employees";
            ResultSet rsColumn = stmt.executeQuery(countColumnSQL);
            if (rsColumn.next()) {
                int totalColumn = rsColumn.getInt("total");
                System.out.println("Total rows (COUNT(department_id)): " + totalColumn);
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

在上述代码中,演示了如何使用 COUNT(1)COUNT(*) 和 COUNT(列名) 进行统计查询。请根据需要调整数据库连接字符串、用户名、密码和 SQL 语句。

执行速度

对 COUNT(1)COUNT(*) 和 COUNT(列名) 的执行速度进行排序,通常在现代的 SQL 数据库管理系统中,COUNT(1) 和 COUNT(*) 的性能基本相同,而 COUNT(列名) 的性能可能略低一些。排序如下:

  • COUNT(1)
  • COUNT(*)
  • COUNT(列名)

详细解释

1. COUNT(1)

  • 执行速度COUNT(1) 只是将每一行的计数加一,现代 SQL 优化器通常会将 COUNT(1) 和 COUNT(*) 优化为相同的执行计划,因此执行速度非常快。
  • 优化器行为: 优化器能够识别 COUNT(1) 的语义并进行优化处理,使其与 COUNT(*) 的性能基本一致。

2. COUNT(*)

  • 执行速度COUNT(*) 计算表中所有行的数量,包括所有列,不忽略任何行。现代 SQL 优化器对此有非常好的优化,因此执行速度也非常快,通常与 COUNT(1) 无异。
  • 优化器行为: 优化器会将 COUNT(*) 优化为高效的行计数操作。

3. COUNT(列名)

  • 执行速度COUNT(列名) 只计算指定列非 NULL 值的行数。在执行过程中,数据库需要检查每一行中特定列是否为 NULL,这会增加一些额外的处理时间。
  • 优化器行为: 尽管现代优化器对 COUNT(列名) 也有优化,但由于需要额外的 NULL 检查,性能可能略低于 COUNT(1) 和 COUNT(*)

示例验证

为了验证上述结论,可以使用以下 SQL 脚本在 MySQL 或其他 SQL 数据库中进行测试。请确保表中有足够多的数据,以便更明显地观察执行时间的差异。

创建测试表并插入数据

CREATE TABLE employees (
    id INT AUTO_INCREMENT PRIMARY KEY,
    department_id INT,
    name VARCHAR(255),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 插入大量数据
INSERT INTO employees (department_id, name) 
SELECT FLOOR(RAND() * 10), CONCAT('Employee', FLOOR(RAND() * 1000))
FROM (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) t1
CROSS JOIN (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) t2
CROSS JOIN (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) t3
CROSS JOIN (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) t4
CROSS JOIN (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) t5;

执行计数查询并记录执行时间

-- 计时 COUNT(1)
SET @start_time = NOW(6);
SELECT COUNT(1) FROM employees;
SELECT TIMEDIFF(NOW(6), @start_time) AS execution_time;

-- 计时 COUNT(*)
SET @start_time = NOW(6);
SELECT COUNT(*) FROM employees;
SELECT TIMEDIFF(NOW(6), @start_time) AS execution_time;

-- 计时 COUNT(department_id)
SET @start_time = NOW(6);
SELECT COUNT(department_id) FROM employees;
SELECT TIMEDIFF(NOW(6), @start_time) AS execution_time;

这些查询将显示每个 COUNT 语句的执行时间。通常,COUNT(1) 和 COUNT(*) 的执行时间几乎相同,而 COUNT(列名) 的执行时间可能稍长一些。

总结

  • COUNT(1): 计算查询结果集中的行数,性能与 COUNT(*) 基本相同。
  • COUNT(*): 计算查询结果集中的总行数,包括所有列,不忽略任何行,通常是最常用和推荐的方式。
  • COUNT(列名): 计算查询结果集中某一列非 NULL 值的行数,适用于统计特定列中的有效数据。

到此这篇关于SQL中count(1)、count(*) 与 count(列名)区别的文章就介绍到这了,更多相关SQL中count(1)、count(*) 与 count(列名)内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • net start mysql服务名无效的三种解决方法

    net start mysql服务名无效的三种解决方法

    这篇文章主要介绍了net start mysql服务名无效的三种解决方法,通过图文结合的方式讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-08-08
  • mysql 数据汇总与分组

    mysql 数据汇总与分组

    这篇文章主要介绍了mysql 数据汇总与分组,我们经常需要汇总数据而不用把它们实际检索出来,为此MySQL提供了专门的函数。使用这些函数,MySQL查询可用于检索数据,以便分析和报表生成。下面来看看具体例子,需要的朋友可以参考一下
    2021-10-10
  • mysql中json_extract的使用方法实例详解

    mysql中json_extract的使用方法实例详解

    MYSQl自带的解析函数JSON_EXTRACT,用JSON_EXTRACT函数解析出来的函数会包含双引号,下面这篇文章主要给大家介绍了关于mysql中json_extract的使用方法,需要的朋友可以参考下
    2023-04-04
  • 解决MySQl查询不区分大小写的方法讲解

    解决MySQl查询不区分大小写的方法讲解

    今天小编就为大家分享一篇关于解决MySQl查询不区分大小写的方法讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-04-04
  • 关于MySQL的索引之最左前缀优化详解

    关于MySQL的索引之最左前缀优化详解

    这篇文章主要介绍了关于MySQL的索引之最左前缀优化详解,多个普通字段组合在一起创建的索引叫做联合索引, 也被称之为组合索引,需要的朋友可以参考下
    2023-05-05
  • MySql主从复制机制全面解析

    MySql主从复制机制全面解析

    这篇文章主要介绍了MySql主从复制机制全面解析的相关资料,帮助大家更好的理解和学习使用MySQL数据库,感兴趣的朋友可以了解下
    2021-04-04
  • mysql 操作总结 INSERT和REPLACE

    mysql 操作总结 INSERT和REPLACE

    用于操作数据库的SQL一般分为两种,一种是查询语句,也就是我们所说的SELECT语句,另外一种就是更新语句,也叫做数据操作语句。
    2009-07-07
  • 超简单的qps统计方法(推荐)

    超简单的qps统计方法(推荐)

    下面小编就为大家带来一篇超简单的qps统计方法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • 高版本Mysql使用group by分组报错的解决方案

    高版本Mysql使用group by分组报错的解决方案

    GROUP BY 语句用于结合合计函数,根据一个或多个列对结果集进行分组,下面这篇文章主要给大家介绍了关于高版本Mysql使用group by分组报错的解决方案,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-03-03
  • mysqlsla慢查询分析工具使用笔记

    mysqlsla慢查询分析工具使用笔记

    mysqlsla是一款帮助语句分析、过滤、和排序的功能,能够处理MySQL慢查询日志、二进制日志等。整体来说, 功能非常强大. 能制作SQL查询数据报表,分析包括执行频率, 数据量, 查询消耗等
    2014-05-05

最新评论