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.pswp.cn/diannao/70959.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/70959.shtml
英文地址,請注明出處:http://en.pswp.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模式;另一種是圖式推理模式,判斷是基于預判,人…