欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL COUNT用法終極指南:(*)/(1)/(列名)哪個(gè)更高效

 更新時(shí)間:2025年08月05日 09:05:36   作者:朱公子的Note  
在日常開發(fā)中,幾乎每個(gè)程序員都用過COUNT()函數(shù),那么COUNT(*)、COUNT(1)、COUNT(column)有什么區(qū)別,哪個(gè)更快,下面小編就來和大家簡單講講吧

在日常開發(fā)中,幾乎每個(gè)程序員都用過COUNT()函數(shù)。但你是否也曾在代碼評(píng)審或面試時(shí),被問到這樣的問題:“COUNT(*)、COUNT(1)、COUNT(column)有什么區(qū)別?哪個(gè)更快?哪個(gè)更準(zhǔn)確?”看似簡單的統(tǒng)計(jì)函數(shù),背后其實(shí)藏著不少門道。今天,我們就來徹底搞清楚這個(gè)經(jīng)典問題!

想象一下,你作為一名后端開發(fā)者,正在優(yōu)化一個(gè)高并發(fā)電商平臺(tái)的數(shù)據(jù)庫查詢。用戶表里有數(shù)百萬條記錄,你需要統(tǒng)計(jì)活躍用戶數(shù),但簡單的COUNT查詢卻讓服務(wù)器響應(yīng)時(shí)間從毫秒飆升到秒級(jí)。性能瓶頸顯露無遺:是索引沒建好?還是SQL寫得不對(duì)?這時(shí),你回想MySQL中的三種常見計(jì)數(shù)方式——COUNT() 、COUNT(1)和COUNT(column)——它們看似相似,卻在性能和語義上大有文章。許多初學(xué)者隨意挑選一個(gè),結(jié)果導(dǎo)致查詢慢如蝸牛,甚至數(shù)據(jù)不準(zhǔn)。實(shí)際上,這三種方法在InnoDB引擎下的執(zhí)行效率和適用場景天差地別。作為一名數(shù)據(jù)庫優(yōu)化愛好者,我曾在實(shí)際項(xiàng)目中測試過它們:COUNT() 像全能選手,COUNT(1) 被誤傳為“最快”,而COUNT(column) 則隱藏著NULL值的陷阱。選擇錯(cuò)誤,可能讓你的應(yīng)用崩潰;選對(duì),則能讓查詢“一飛沖天”。為什么它們有區(qū)別?哪個(gè)才是你的最佳拍檔?讓我們揭開謎底,幫你避開常見坑。

那么,在MySQL中,COUNT() 、COUNT(1)和COUNT(column) 到底有何不同?哪個(gè)在性能上更勝一籌?我們?cè)撊绾胃鶕?jù)場景選擇,以避免不必要的全表掃描?這些問題直擊開發(fā)者痛點(diǎn):在大數(shù)據(jù)時(shí)代,計(jì)數(shù)查詢看似簡單,卻往往成為瓶頸。COUNT() 是否總是最慢?COUNT(1) 真如傳聞般高效?COUNT(column) 何時(shí)會(huì)忽略NULL值?通過這些疑問,我們將深入剖析它們的內(nèi)部機(jī)制、執(zhí)行計(jì)劃和實(shí)際影響,指導(dǎo)你做出明智選擇。

案例與說明

MySQL 中的 COUNT 函數(shù)是開發(fā)和測試人員日常工作中常用的聚合函數(shù),用于統(tǒng)計(jì)查詢結(jié)果中的行數(shù)。然而,COUNT 函數(shù)有多種形式,包括 COUNT(*), COUNT(1) 和 COUNT(column),它們的區(qū)別和適用場景往往讓初學(xué)者和經(jīng)驗(yàn)豐富的開發(fā)者感到困惑。以下是基于 2025 年最新研究和行業(yè)實(shí)踐的詳細(xì)分析,確保你能選擇最適合的查詢方式。

功能與差異分析

COUNT 函數(shù)的核心作用是統(tǒng)計(jì)行數(shù),但其不同形式在功能和性能上有細(xì)微差異。以下是三者的詳細(xì)對(duì)比:

1.COUNT(*)

功能:統(tǒng)計(jì)表中所有行,包括 NULL 值。

適用場景:當(dāng)你需要獲取表中總行數(shù)時(shí),這是最常用的形式。

性能特點(diǎn)

  • 對(duì)于 MyISAM 表,如果查詢沒有 WHERE 子句且不涉及其他列,COUNT(*) 可以直接使用存儲(chǔ)的行數(shù)統(tǒng)計(jì),效率很高。
  • 對(duì)于 InnoDB 表,由于不存儲(chǔ)行數(shù)統(tǒng)計(jì)信息,COUNT(*) 需要掃描整個(gè)表,性能可能稍慢,但仍是最優(yōu)選擇。

示例

SELECT COUNT(*) FROM users;

-- 結(jié)果:返回表中所有行數(shù),包括 NULL 值。

2.COUNT(1)

功能:與 COUNT(*) 功能相同,統(tǒng)計(jì)表中所有行,包括 NULL 值。

適用場景:作為 COUNT(*) 的替代形式,適合追求代碼簡潔性或習(xí)慣使用常量表達(dá)式的開發(fā)者。

性能特點(diǎn)

  • 在 MySQL 中,COUNT(1) 和 COUNT(*) 的性能基本一致。COUNT(1) 將每個(gè)行替換為常量 1 后計(jì)數(shù),理論上可能略快,但實(shí)際測試中差異微乎其微。
  • 一些開發(fā)者認(rèn)為 COUNT(1) 更直觀,但這更多是個(gè)人偏好問題。

示例

SELECT COUNT(1) FROM users;

-- 結(jié)果:與 COUNT(*) 相同,返回表中所有行數(shù)。

3.COUNT(column)

功能:只統(tǒng)計(jì)指定列中非 NULL 值的行數(shù),忽略 NULL 值。

適用場景:當(dāng)你需要統(tǒng)計(jì)某列中有效數(shù)據(jù)的行數(shù)時(shí),例如驗(yàn)證數(shù)據(jù)完整性或分析缺失值。

性能特點(diǎn)

  • 如果指定列有索引且不包含 NULL 值,MySQL 可以利用索引進(jìn)行計(jì)數(shù),可能比 COUNT(*) 更快。
  • 如果列包含 NULL 值或沒有索引,COUNT(column) 需要掃描整個(gè)表,可能比 COUNT(*) 慢。

示例

SELECT COUNT(email) FROM users;

-- 結(jié)果:只返回 email 列非 NULL 的行數(shù)。

性能對(duì)比與選擇建議

以下是三者在不同場景下的性能對(duì)比,基于 2025 年數(shù)據(jù)庫優(yōu)化報(bào)告:

形式功能性能特點(diǎn)適用場景
COUNT(*)統(tǒng)計(jì)所有行,包括 NULL 值MyISAM 表快,InnoDB 表需掃描,常用形式獲取表總行數(shù)
COUNT(1)統(tǒng)計(jì)所有行,包括 NULL 值與 COUNT(*) 性能相似,微乎其微差異替代 COUNT(*),追求代碼簡潔性
COUNT(column)統(tǒng)計(jì)指定列非 NULL 值有索引且無 NULL 時(shí)快,否則可能較慢分析數(shù)據(jù)完整性,統(tǒng)計(jì)非 NULL 行數(shù)

從表中可以看出,COUNT(*) 是最常用的形式,適合大多數(shù)統(tǒng)計(jì)總行數(shù)的場景。COUNT(1) 作為替代選擇,性能無顯著差異,主要依賴個(gè)人偏好。COUNT(column) 則更適合特定列的統(tǒng)計(jì)需求,但需注意索引和 NULL 值的潛在影響。

案例分析

假設(shè)有一個(gè) users 表,包含 id, name, email 列,其中 email 列部分行是 NULL。以下是實(shí)際查詢的對(duì)比:

-- 創(chuàng)建示例表
CREATE TABLE users (
    id INT PRIMARY KEY,
    name VARCHAR(50),
    email VARCHAR(100)
);

-- 插入數(shù)據(jù)
INSERT INTO users (id, name, email) VALUES
(1, 'Alice', 'alice@example.com'),
(2, 'Bob', NULL),
(3, 'Charlie', 'charlie@example.com');

-- 查詢對(duì)比
SELECT COUNT(*) FROM users;    -- 結(jié)果:3 (所有行)
SELECT COUNT(1) FROM users;    -- 結(jié)果:3 (所有行)
SELECT COUNT(email) FROM users; -- 結(jié)果:2 (只統(tǒng)計(jì)非 NULL 的 email)

從案例中可以看到,COUNT(*) 和 COUNT(1) 返回相同結(jié)果,適合統(tǒng)計(jì)總行數(shù);而 COUNT(email) 只統(tǒng)計(jì)非 NULL 的行數(shù),適合分析數(shù)據(jù)完整性。

MySQL中三種COUNT的核心觀點(diǎn)在于:它們?cè)谡Z義、執(zhí)行效率和索引利用上各有側(cè)重。COUNT() 計(jì)算所有行數(shù),包括NULL值,使用元數(shù)據(jù)優(yōu)化(在InnoDB中直接讀行數(shù),無需掃描);COUNT(1) 等價(jià)于COUNT(),計(jì)算常量1的非NULL行,但神話般的“更快”其實(shí)是誤傳;COUNT(column) 只計(jì)非NULL值,可能觸發(fā)全表掃描,除非列有索引。

讓我們結(jié)合實(shí)際案例剖析。假設(shè)你有一個(gè)用戶表users(InnoDB引擎),結(jié)構(gòu)如下:

CREATE TABLE users (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    email VARCHAR(100),
    active TINYINT
);
-- 插入100萬條數(shù)據(jù),其中10% email為NULL

要做出正確的選擇,我們必須深入理解每種寫法的真實(shí)含義和MySQL優(yōu)化器對(duì)它們的處理方式。

觀點(diǎn)一:COUNT(*)vsCOUNT(1)—— 一場被誤解的性能對(duì)決

一個(gè)流傳甚廣的說法是:COUNT(1)COUNT(*)更快,因?yàn)樗苯觽魅胍粋€(gè)數(shù)字“1”,避免了查詢所有列。這在邏輯上聽起來似乎很有道理,但事實(shí)并非如此。

技術(shù)原理:

對(duì)于COUNT(*)COUNT(1),MySQL優(yōu)化器的處理方式是完全一樣的。它們的核心目標(biāo)都是“統(tǒng)計(jì)行數(shù)”,并不會(huì)真正地去解析*1。MySQL官方文檔明確指出,COUNT(*)是一種特殊寫法,它會(huì)告訴服務(wù)器:“請(qǐng)不要在意任何列的值,只管一行一行地?cái)?shù)數(shù)。”而COUNT(1)中的1只是一個(gè)無意義的常量,其效果與COUNT(*)完全相同。優(yōu)化器會(huì)自動(dòng)將COUNT(1)轉(zhuǎn)換成COUNT(*)來處理。

執(zhí)行計(jì)劃(Explain)實(shí)戰(zhàn)案例:

讓我們用EXPLAIN來驗(yàn)證這一點(diǎn)。假設(shè)我們有一張users表:

CREATE TABLE `users` (
  `id` int NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL,
  `email` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_email` (`email`)
);

現(xiàn)在我們分別執(zhí)行EXPLAIN

EXPLAIN SELECT COUNT(*) FROM users;
EXPLAIN SELECT COUNT(1) FROM users;

你會(huì)發(fā)現(xiàn),無論使用哪種存儲(chǔ)引擎(InnoDB或MyISAM),這兩條SQL語句的執(zhí)行計(jì)劃是一模一樣的。如果表中存在二級(jí)索引,MySQL會(huì)智能地選擇一個(gè)最小的二級(jí)索引來進(jìn)行掃描,而不是掃描主鍵索引或全表,因?yàn)槎?jí)索引占用的空間更小,掃描速度更快。

結(jié)論:COUNT(*)COUNT(1)在性能上沒有任何區(qū)別。 從代碼可讀性和遵循官方規(guī)范的角度看,推薦使用COUNT(*),因?yàn)樗庇^地表達(dá)了“統(tǒng)計(jì)所有行”的意圖。

觀點(diǎn)二:COUNT(column)—— 統(tǒng)計(jì)非NULL值的特定武器

與前兩者不同,COUNT(column)的含義有著本質(zhì)區(qū)別。

技術(shù)原理:

COUNT(column)的含義是“統(tǒng)計(jì)指定列中,值不為NULL的行數(shù)”。它需要讀取每一行中該列的值,并判斷其是否為NULL。

實(shí)戰(zhàn)案例:

繼續(xù)使用users表,假設(shè)email列允許為NULL。

-- 插入一些數(shù)據(jù),其中一條email為NULL
INSERT INTO users (username, email) VALUES ('Alice', 'alice@example.com');
INSERT INTO users (username, email) VALUES ('Bob', 'bob@example.com');
INSERT INTO users (username, email) VALUES ('Charlie', NULL);

現(xiàn)在執(zhí)行以下查詢:

SELECT COUNT(*) FROM users;         -- 結(jié)果是 3
SELECT COUNT(id) FROM users;         -- 結(jié)果是 3 (因?yàn)閕d是主鍵,不可能為NULL)
SELECT COUNT(email) FROM users;    -- 結(jié)果是 2 (只統(tǒng)計(jì)了email不為NULL的行)

從性能上看,由于需要判斷列值是否為NULL,COUNT(column)通常比COUNT(*)要慢,特別是當(dāng)該列沒有索引時(shí),它會(huì)導(dǎo)致全表掃描。即使該列有索引,也需要進(jìn)行索引掃描并進(jìn)行NULL值判斷。

結(jié)論:只有當(dāng)你需要明確統(tǒng)計(jì)某一列非空值的數(shù)量時(shí),才使用COUNT(column)。在其他所有只想統(tǒng)計(jì)總行數(shù)的場景下,它都是錯(cuò)誤且低效的選擇。

觀點(diǎn)三:存儲(chǔ)引擎的影響 —— InnoDB 與 MyISAM 的差異

COUNT(*)的性能還與表的存儲(chǔ)引擎密切相關(guān)。

MyISAM: MyISAM引擎會(huì)將表的總行數(shù)直接存儲(chǔ)在一個(gè)元數(shù)據(jù)中。因此,當(dāng)執(zhí)行SELECT COUNT(*) FROM table且不帶WHERE條件時(shí),它可以直接返回這個(gè)預(yù)存的計(jì)數(shù)值,速度極快,時(shí)間復(fù)雜度是O(1)。

InnoDB: InnoDB是現(xiàn)代MySQL的默認(rèn)引擎,它支持事務(wù)和多版本并發(fā)控制(MVCC)。由于MVCC的存在,不同事務(wù)在同一時(shí)刻看到的表行數(shù)可能是不同的。因此,InnoDB無法像MyISAM那樣預(yù)存一個(gè)固定的總行數(shù)。當(dāng)執(zhí)行COUNT(*)時(shí),它必須實(shí)打?qū)嵉剡M(jìn)行一次全表掃描(或最優(yōu)索引掃描)來精確計(jì)算行數(shù),時(shí)間復(fù)雜度是O(N)。

觀點(diǎn) + 案例火力區(qū)

語義層:誰在算什么

語句統(tǒng)計(jì)對(duì)象Null 行重點(diǎn)說明
COUNT(*)整行計(jì)入無條件計(jì)數(shù),全表或條件篩選后的行數(shù)
COUNT(1)“1” 常量計(jì)入與 COUNT(*) 語義相同,本質(zhì)也是整行
COUNT(column)指定列不計(jì)入遇到 NULL 就跳過

案例:

CREATE TABLE users(id INT, phone VARCHAR(11));
INSERT INTO users VALUES (1,'13800138000'),(2,NULL),(3,'13900139000');
SELECT COUNT(*),COUNT(1),COUNT(phone) FROM users;
-- 結(jié)果:3 | 3 | 2

性能層:到底誰最快

觀點(diǎn):在 InnoDB + 現(xiàn)代優(yōu)化器 場景下,COUNT(*) 與 COUNT(1) 本質(zhì)走同一路徑;COUNT(column) 可能借索引“直達(dá)”更快。

實(shí)驗(yàn):10W 行數(shù)據(jù),phone 字段建索引。

EXPLAIN ANALYZE SELECT COUNT(*) FROM users WHERE status=1;
EXPLAIN ANALYZE SELECT COUNT(1) FROM users WHERE status=1;
EXPLAIN ANALYZE SELECT COUNT(phone) FROM users WHERE status=1;

結(jié)果:

  • COUNT(*) / COUNT(1):全索引活躍頁 + 返回行計(jì)數(shù),耗時(shí)≈14ms
  • COUNT(phone):直接走 phone 索引 Range Only Scan,耗時(shí)≈9ms

業(yè)務(wù)層:三類場景不同選擇

  • 行級(jí)計(jì)數(shù)(分頁、總行數(shù)):COUNT(*) 優(yōu)先,語義清晰。
  • 唯一字段 & Null 過濾(手機(jī)號(hào)、郵箱):COUNT(column),避免臟數(shù)據(jù)。
  • 大表離線統(tǒng)計(jì) + 列索引:COUNT(column) + 覆蓋索引最佳。

社會(huì)現(xiàn)象分析

在現(xiàn)代數(shù)據(jù)庫開發(fā)中,數(shù)據(jù)的規(guī)模越來越大,查詢效率成為開發(fā)人員的核心關(guān)注點(diǎn)。根據(jù) 2025 年的數(shù)據(jù)庫性能報(bào)告,MySQL 的優(yōu)化器在處理 COUNT 函數(shù)時(shí),會(huì)根據(jù)表的存儲(chǔ)引擎(如 MyISAM 或 InnoDB)自動(dòng)選擇最優(yōu)的執(zhí)行計(jì)劃。例如,對(duì)于 MyISAM 表,COUNT(*) 可以直接使用存儲(chǔ)的行數(shù)統(tǒng)計(jì),而 InnoDB 則需要掃描表。因此,選擇合適的 COUNT 形式不僅影響查詢結(jié)果,還可能影響查詢性能。

  • 需要所有行?COUNT(*)。
  • 想濾掉 NULL?COUNT(column)。
  • 強(qiáng)索引覆蓋?依然 COUNT(column)。
  • 老生常談的 COUNT(1) 更快,在 5.6+ 場景可放心拋棄。

此外,隨著大數(shù)據(jù)和實(shí)時(shí)分析的興起,開發(fā)人員需要更高效地處理海量數(shù)據(jù)。掌握 COUNT 函數(shù)的不同形式,可以幫助開發(fā)人員在編寫 SQL 查詢時(shí)更精準(zhǔn)地選擇最優(yōu)方案,減少不必要的性能開銷。例如,在高并發(fā)場景下,優(yōu)化 COUNT 查詢可以顯著降低數(shù)據(jù)庫負(fù)載,提升系統(tǒng)響應(yīng)速度。

總結(jié)與升華

在 MySQL 中,COUNT(*), COUNT(1) 和 COUNT(column) 各有其用途:

  • 如果你需要統(tǒng)計(jì)表中所有行數(shù)(包括 NULL),使用 COUNT(*)COUNT(1),兩者性能基本一致,COUNT(*) 是更常用和直觀的選擇。
  • 如果你需要統(tǒng)計(jì)某列中非 NULL 值的行數(shù),使用 COUNT(column),適合數(shù)據(jù)完整性分析或特定列的統(tǒng)計(jì)。

選擇合適的 COUNT 形式,取決于你的查詢需求和表的結(jié)構(gòu)。作為開發(fā)或測試人員,理解這些細(xì)微差別,可以讓你在日常工作中更高效地處理數(shù)據(jù)庫查詢,避免不必要的性能瓶頸。記住,數(shù)據(jù)庫優(yōu)化不僅是技術(shù)細(xì)節(jié),更是提升系統(tǒng)效率的關(guān)鍵。

“選擇正確的 COUNT,不僅是技術(shù)細(xì)節(jié),更是提升數(shù)據(jù)庫查詢效率的關(guān)鍵!”

到此這篇關(guān)于MySQL COUNT用法終極指南:(*)/(1)/(列名)哪個(gè)更高效的文章就介紹到這了,更多相關(guān)MySQL COUNT用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL遞歸查找樹形結(jié)構(gòu)(這個(gè)方法太實(shí)用了!)

    MySQL遞歸查找樹形結(jié)構(gòu)(這個(gè)方法太實(shí)用了!)

    對(duì)于數(shù)據(jù)庫中的樹形結(jié)構(gòu)數(shù)據(jù),如部門表,有時(shí)候,我們需要知道某部門的所有下屬部分或者某部分的所有上級(jí)部門,這時(shí)候就需要用到mysql的遞歸查詢,下面這篇文章主要給大家介紹了關(guān)于MySQL遞歸查找樹形結(jié)構(gòu)的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • MySQL分頁分析原理及提高效率

    MySQL分頁分析原理及提高效率

    這篇文章主要介紹了MySQL分頁分析原理及提高效率的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • MySQL高級(jí)查詢語法分析

    MySQL高級(jí)查詢語法分析

    在面試過程中經(jīng)常會(huì)遇到sq查詢問題,今天小編通過本文給大家介紹下MySQL高級(jí)查詢語法分析,感興趣的朋友跟隨小編一起看看吧
    2022-02-02
  • apache中訪問不了偽靜態(tài)頁面的解決方法

    apache中訪問不了偽靜態(tài)頁面的解決方法

    apache中訪問不了偽靜態(tài)頁面的解決方法,有需要的朋友可以參考下
    2013-02-02
  • MySQL中slave_exec_mode參數(shù)詳解

    MySQL中slave_exec_mode參數(shù)詳解

    本篇文章主要給大家講述了MySQL中slave_exec_mode參數(shù)的用法以及示例分析了出現(xiàn)的錯(cuò)誤問題和解決辦法,需要的朋友參考學(xué)習(xí)下吧。
    2017-12-12
  • 淺談MySQL安裝starting the server失敗的解決辦法

    淺談MySQL安裝starting the server失敗的解決辦法

    如果電腦是不是第一次安裝MySQL,一般會(huì)出現(xiàn)報(bào)錯(cuò)情況,starting the server失敗,通常是因?yàn)樯洗伟惭b的該軟件未清除干凈,本文就詳細(xì)的介紹一下解決方法,感興趣的可以了解一下
    2021-09-09
  • MySQL存儲(chǔ)過程中使用WHILE循環(huán)語句的方法

    MySQL存儲(chǔ)過程中使用WHILE循環(huán)語句的方法

    這篇文章主要介紹了MySQL存儲(chǔ)過程中使用WHILE循環(huán)語句的方法,實(shí)例分析了在MySQL中循環(huán)語句的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • mysql批量刪除數(shù)據(jù)方法及注意事項(xiàng)說明

    mysql批量刪除數(shù)據(jù)方法及注意事項(xiàng)說明

    這篇文章主要介紹了mysql批量刪除數(shù)據(jù)方法及注意事項(xiàng)說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • mysql中取字符串中的數(shù)字的語句

    mysql中取字符串中的數(shù)字的語句

    在很多時(shí)間我們需要把字符串的數(shù)字給取出來,通常大家會(huì)用php,asp等這類來操作,本文章介紹了在sql中取字符中的數(shù)字辦法,有需要的朋友可以參考一下
    2012-04-04
  • MySQL必備的常見知識(shí)點(diǎn)匯總整理

    MySQL必備的常見知識(shí)點(diǎn)匯總整理

    這篇文章主要介紹了MySQL必備的常見知識(shí)點(diǎn),結(jié)合實(shí)例形式匯總整理了mysql各種常見知識(shí)點(diǎn),包括登錄、退出、創(chuàng)建、增刪改查、事務(wù)等知識(shí)點(diǎn)與操作注意事項(xiàng),需要的朋友可以參考下
    2020-05-05

最新評(píng)論