SQL中count(1)、count(*)?與?count(列名)的區(qū)別詳細(xì)解釋
前言
在 SQL 中,COUNT
函數(shù)用于計(jì)算查詢結(jié)果集中的行數(shù)。COUNT(1)
、COUNT(*)
和 COUNT(列名)
都可以用來(lái)統(tǒng)計(jì)行數(shù),但它們?cè)趯?shí)現(xiàn)細(xì)節(jié)和使用場(chǎng)景上有一些區(qū)別。以下是詳細(xì)的解釋?zhuān)?/p>
1. COUNT(1)
- 定義:
COUNT(1)
計(jì)算查詢結(jié)果集中的行數(shù)。 - 實(shí)現(xiàn): 在執(zhí)行過(guò)程中,
COUNT(1)
會(huì)將1
作為一個(gè)非空的常量值,并對(duì)每一行進(jìn)行計(jì)數(shù)。 - 效率: 現(xiàn)代的 SQL 優(yōu)化器通常會(huì)將
COUNT(1)
和COUNT(*)
優(yōu)化為相同的執(zhí)行計(jì)劃,因此性能基本相同。 - 用途: 適用于計(jì)算總行數(shù),與
COUNT(*)
無(wú)區(qū)別。
SELECT COUNT(1) FROM employees;
2. COUNT(*)
- 定義:
COUNT(*)
計(jì)算查詢結(jié)果集中的總行數(shù),包括所有列,不會(huì)忽略任何行,即使某些列包含NULL
。 - 實(shí)現(xiàn): SQL 優(yōu)化器會(huì)對(duì)
COUNT(*)
進(jìn)行優(yōu)化,將其轉(zhuǎn)換為統(tǒng)計(jì)行數(shù)的操作。 - 效率: 通常是最常用和推薦的方式,因?yàn)槠湔Z(yǔ)義明確且優(yōu)化器能夠很好地處理。
- 用途: 適用于計(jì)算總行數(shù),性能通常優(yōu)于
COUNT(列名)
。
SELECT COUNT(*) FROM employees;
3. COUNT(列名)
- 定義:
COUNT(列名)
計(jì)算查詢結(jié)果集中某一列非NULL
值的行數(shù)。 - 實(shí)現(xiàn): 只有當(dāng)指定列的值不為
NULL
時(shí),該行才會(huì)被計(jì)入結(jié)果。 - 效率: 由于需要檢查每行中的特定列是否為
NULL
,性能可能略低于COUNT(*)
和COUNT(1)
。 - 用途: 適用于計(jì)算某一特定列中非
NULL
值的數(shù)量。
SELECT COUNT(department_id) FROM employees;
示例代碼
下面是一個(gè)使用 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(列名)
進(jìn)行統(tǒng)計(jì)查詢。請(qǐng)根據(jù)需要調(diào)整數(shù)據(jù)庫(kù)連接字符串、用戶名、密碼和 SQL 語(yǔ)句。
執(zhí)行速度
對(duì) COUNT(1)
、COUNT(*)
和 COUNT(列名)
的執(zhí)行速度進(jìn)行排序,通常在現(xiàn)代的 SQL 數(shù)據(jù)庫(kù)管理系統(tǒng)中,COUNT(1)
和 COUNT(*)
的性能基本相同,而 COUNT(列名)
的性能可能略低一些。排序如下:
- COUNT(1)
- COUNT(*)
- COUNT(列名)
詳細(xì)解釋
1. COUNT(1)
- 執(zhí)行速度:
COUNT(1)
只是將每一行的計(jì)數(shù)加一,現(xiàn)代 SQL 優(yōu)化器通常會(huì)將COUNT(1)
和COUNT(*)
優(yōu)化為相同的執(zhí)行計(jì)劃,因此執(zhí)行速度非???。 - 優(yōu)化器行為: 優(yōu)化器能夠識(shí)別
COUNT(1)
的語(yǔ)義并進(jìn)行優(yōu)化處理,使其與COUNT(*)
的性能基本一致。
2. COUNT(*)
- 執(zhí)行速度:
COUNT(*)
計(jì)算表中所有行的數(shù)量,包括所有列,不忽略任何行?,F(xiàn)代 SQL 優(yōu)化器對(duì)此有非常好的優(yōu)化,因此執(zhí)行速度也非常快,通常與COUNT(1)
無(wú)異。 - 優(yōu)化器行為: 優(yōu)化器會(huì)將
COUNT(*)
優(yōu)化為高效的行計(jì)數(shù)操作。
3. COUNT(列名)
- 執(zhí)行速度:
COUNT(列名)
只計(jì)算指定列非NULL
值的行數(shù)。在執(zhí)行過(guò)程中,數(shù)據(jù)庫(kù)需要檢查每一行中特定列是否為NULL
,這會(huì)增加一些額外的處理時(shí)間。 - 優(yōu)化器行為: 盡管現(xiàn)代優(yōu)化器對(duì)
COUNT(列名)
也有優(yōu)化,但由于需要額外的NULL
檢查,性能可能略低于COUNT(1)
和COUNT(*)
。
示例驗(yàn)證
為了驗(yàn)證上述結(jié)論,可以使用以下 SQL 腳本在 MySQL 或其他 SQL 數(shù)據(jù)庫(kù)中進(jìn)行測(cè)試。請(qǐng)確保表中有足夠多的數(shù)據(jù),以便更明顯地觀察執(zhí)行時(shí)間的差異。
創(chuàng)建測(cè)試表并插入數(shù)據(jù)
CREATE TABLE employees ( id INT AUTO_INCREMENT PRIMARY KEY, department_id INT, name VARCHAR(255), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 插入大量數(shù)據(jù) 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;
執(zhí)行計(jì)數(shù)查詢并記錄執(zhí)行時(shí)間
-- 計(jì)時(shí) COUNT(1) SET @start_time = NOW(6); SELECT COUNT(1) FROM employees; SELECT TIMEDIFF(NOW(6), @start_time) AS execution_time; -- 計(jì)時(shí) COUNT(*) SET @start_time = NOW(6); SELECT COUNT(*) FROM employees; SELECT TIMEDIFF(NOW(6), @start_time) AS execution_time; -- 計(jì)時(shí) COUNT(department_id) SET @start_time = NOW(6); SELECT COUNT(department_id) FROM employees; SELECT TIMEDIFF(NOW(6), @start_time) AS execution_time;
這些查詢將顯示每個(gè) COUNT
語(yǔ)句的執(zhí)行時(shí)間。通常,COUNT(1)
和 COUNT(*)
的執(zhí)行時(shí)間幾乎相同,而 COUNT(列名)
的執(zhí)行時(shí)間可能稍長(zhǎng)一些。
總結(jié)
COUNT(1)
: 計(jì)算查詢結(jié)果集中的行數(shù),性能與COUNT(*)
基本相同。COUNT(*)
: 計(jì)算查詢結(jié)果集中的總行數(shù),包括所有列,不忽略任何行,通常是最常用和推薦的方式。COUNT(列名)
: 計(jì)算查詢結(jié)果集中某一列非NULL
值的行數(shù),適用于統(tǒng)計(jì)特定列中的有效數(shù)據(jù)。
到此這篇關(guān)于SQL中count(1)、count(*) 與 count(列名)區(qū)別的文章就介紹到這了,更多相關(guān)SQL中count(1)、count(*) 與 count(列名)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- mysql count(*)分組之后IFNULL無(wú)效問(wèn)題
- Sql根據(jù)不同條件統(tǒng)計(jì)總數(shù)的方法(count和sum)
- MySQL數(shù)據(jù)庫(kù)統(tǒng)計(jì)函數(shù)COUNT的使用及說(shuō)明
- mysql?count()函數(shù)不計(jì)算null和空值問(wèn)題
- mysql數(shù)據(jù)庫(kù)之count()函數(shù)和sum()函數(shù)用法及區(qū)別說(shuō)明
- mysql一條sql查出多個(gè)條件不同的sum或count問(wèn)題
- MySQL中的count(*)?和?count(1)?區(qū)別性能對(duì)比分析
- SQL 中 COUNT 的用法示例詳解
相關(guān)文章
- InnoDB是為Mysql處理巨大數(shù)據(jù)量時(shí)的最大性能設(shè)計(jì)。它的CPU效率可能是任何其它基于磁盤(pán)的關(guān)系數(shù)據(jù)庫(kù)引擎所不能匹敵的。在數(shù)據(jù)量大的網(wǎng)站或是應(yīng)用中Innodb是倍受青睞的。那么它就不需要優(yōu)化了嗎,答案很顯然:當(dāng)然不是?。。?/div> 2017-03-03
MySQL使用select語(yǔ)句查詢指定表中指定列(字段)的數(shù)據(jù)
本文介紹MySQL數(shù)據(jù)庫(kù)中執(zhí)行select查詢語(yǔ)句,查詢指定列的數(shù)據(jù),即指定字段的數(shù)據(jù),需要的朋友可以參考下2016-11-11sql如何使用group by分組,同時(shí)查詢其它字段
文章介紹了使用SQL的GROUP BY進(jìn)行分組查詢時(shí)的一些規(guī)則和技巧,主要強(qiáng)調(diào)了在SELECT后面的字段要么是聚合函數(shù)的一部分,要么必須包含在GROUP BY子句中,此外,文章還討論了如何在GROUP BY時(shí)查詢其他字段,通過(guò)使用MAX或MIN函數(shù)來(lái)實(shí)現(xiàn)2024-12-12解決mysql 組合AND和OR帶來(lái)的問(wèn)題
這篇文章主要介紹了解決mysql 組合AND和OR帶來(lái)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11最新評(píng)論