首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

SELECT COUNT(*) vs COUNT(1) vs COUNT(列名):性能差異與使用場景全解析

     編輯:MySQL 綜合教學

SELECT COUNT(*) vs COUNT(1) vs COUNT(列名):性能差異與使用場景全解析

結果一致性

  • COUNT(*)、COUNT(1)、COUNT(常量):統計所有行數,包含 NULL 行。
  • COUNT(列名):統計該列非 NULL 值的行數,不包含 NULL。

性能對比 (InnoDB)

場景最快寫法原因
表有主鍵COUNT(主鍵列)聚簇索引葉節點即主鍵,掃描最小 (非葉節點不存數據)
表無主鍵COUNT(1) ≈ COUNT(*)需掃描二級索引或全表,常量無額外列讀取開銷
單列表COUNT(*)唯一列即主鍵/聚簇索引

本質:InnoDB 並不存儲行數,需掃描索引統計。優化器會自動選擇最小的二級索引 (或主鍵) 掃描。COUNT(1) 和 COUNT(*) 現代優化器內部處理完全一致,無性能差異。

常見誤區澄清

  1. 誤區:COUNT(*) 比 COUNT(1) 慢,因為要讀所有列。
    真相:優化器不會讀取行數據,只遍歷索引條目計數。
  2. 誤區:COUNT(1) 是統計常量 1 的個數。
    真相:語法糖,語義等同 COUNT(*)。

延伸:SELECT 1 vs SELECT *

  • SELECT 1 FROM t WHERE ...:返回滿足條件的行數個「1」,常用於 EXISTS 子查詢,只需遍歷索引判斷存在性,無需回表讀列,比 SELECT * 快。
  • SELECT SUM(1):等同 COUNT(*),但 SUM 可傳入任意數值 (含負數/浮點),結果為 值 × 行數。

最佳實踐建議

  1. 統計總行數:習慣用 COUNT(*) (標準 SQL、語義清晰、優化器最優)。
  2. 統計非空行數:COUNT(具體列名)。
  3. 存在性檢查:EXISTS (SELECT 1 ...)。
  4. 避免在大表頻繁執行 COUNT(*),考慮緩存計數、觸發器維護計數表或近似算法 (如 EXPLAIN rows 估值)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved