【SQL】count(1)、count(*) 与 count(列名) 的区别

打印 上一主题 下一主题

主题 1036|帖子 1036|积分 3108

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

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



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



  • 定义: COUNT(*) 计算查询结果会合的总行数,包括所有列,不会忽略任何行,即使某些列包含 NULL。
  • 实现: SQL 优化器会对 COUNT(*) 举行优化,将其转换为统计行数的操纵。
  • 服从: 通常是最常用和推荐的方式,因为其语义明确且优化器能够很好地处置处罚。
  • 用途: 适用于计算总行数,性能通常优于 COUNT(列名)。
  1. SELECT COUNT(*) FROM employees;
复制代码
3. COUNT(列名)



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

下面是一个使用 JDBC 示例代码,展示怎样使用 COUNT(1)、COUNT(*) 和 COUNT(列名):
  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.Statement;
  4. import java.sql.ResultSet;
  5. import java.sql.SQLException;
  6. public class CountExample {
  7.     private static final String JDBC_URL = "jdbc:mysql://localhost:3306/yourdatabase";
  8.     private static final String JDBC_USER = "yourusername";
  9.     private static final String JDBC_PASSWORD = "yourpassword";
  10.     public static void main(String[] args) {
  11.         try (Connection conn = DriverManager.getConnection(JDBC_URL, JDBC_USER, JDBC_PASSWORD);
  12.              Statement stmt = conn.createStatement()) {
  13.             // 使用 COUNT(1)
  14.             String count1SQL = "SELECT COUNT(1) AS total FROM employees";
  15.             ResultSet rs1 = stmt.executeQuery(count1SQL);
  16.             if (rs1.next()) {
  17.                 int total1 = rs1.getInt("total");
  18.                 System.out.println("Total rows (COUNT(1)): " + total1);
  19.             }
  20.             // 使用 COUNT(*)
  21.             String countAllSQL = "SELECT COUNT(*) AS total FROM employees";
  22.             ResultSet rsAll = stmt.executeQuery(countAllSQL);
  23.             if (rsAll.next()) {
  24.                 int totalAll = rsAll.getInt("total");
  25.                 System.out.println("Total rows (COUNT(*)): " + totalAll);
  26.             }
  27.             // 使用 COUNT(column)
  28.             String countColumnSQL = "SELECT COUNT(department_id) AS total FROM employees";
  29.             ResultSet rsColumn = stmt.executeQuery(countColumnSQL);
  30.             if (rsColumn.next()) {
  31.                 int totalColumn = rsColumn.getInt("total");
  32.                 System.out.println("Total rows (COUNT(department_id)): " + totalColumn);
  33.             }
  34.         } catch (SQLException e) {
  35.             e.printStackTrace();
  36.         }
  37.     }
  38. }
复制代码
在上述代码中,演示了怎样使用 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 数据库中举行测试。请确保表中有充足多的数据,以便更显着地观察执行时间的差异。
创建测试表并插入数据

  1. CREATE TABLE employees (
  2.     id INT AUTO_INCREMENT PRIMARY KEY,
  3.     department_id INT,
  4.     name VARCHAR(255),
  5.     created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
  6. );
  7. -- 插入大量数据
  8. INSERT INTO employees (department_id, name)
  9. SELECT FLOOR(RAND() * 10), CONCAT('Employee', FLOOR(RAND() * 1000))
  10. FROM (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) t1
  11. CROSS JOIN (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) t2
  12. CROSS JOIN (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) t3
  13. CROSS JOIN (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) t4
  14. CROSS JOIN (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) t5;
复制代码
执行计数查询并记录执行时间

  1. -- 计时 COUNT(1)SET @start_time = NOW(6);SELECT COUNT(1) FROM employees;
  2. SELECT TIMEDIFF(NOW(6), @start_time) AS execution_time;-- 计时 COUNT(*)SET @start_time = NOW(6);SELECT COUNT(*) FROM employees;
  3. SELECT TIMEDIFF(NOW(6), @start_time) AS execution_time;-- 计时 COUNT(department_id)SET @start_time = NOW(6);SELECT COUNT(department_id) FROM employees;
  4. SELECT TIMEDIFF(NOW(6), @start_time) AS execution_time;
复制代码
这些查询将显示每个 COUNT 语句的执行时间。通常,COUNT(1) 和 COUNT(*) 的执行时间险些雷同,而 COUNT(列名) 的执行时间可能稍长一些。
总结



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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

商道如狼道

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表