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

SQL 性能調優日常筆記:COUNT(*) vs COUNT(1) vs COUNT(col) 真相

     編輯:Oracle 教學

常見迷思:COUNT(*) 慢、COUNT(1) 快?

網路上流傳「COUNT(1) 比 COUNT(*) 快」,實際情況取決於**表結構與執行計畫**。

核心結論對照表

場景最快寫法說明
表**無主鍵**COUNT(1)全表掃描時,1 為常數不需讀取行資料,略快於 *(需展開所有欄位元數據)
表**有主鍵**COUNT(主鍵欄位)優化器可直接掃描主鍵索引(通常較窄),避免全表掃描
表**只有一個欄位**COUNT(*)無額外開銷,語義最清晰

語義差異:NULL 的處理

  • COUNT(*)、COUNT(1)、COUNT(常數):**包含 NULL 行**,統計滿足 WHERE 條件的**行數**。
  • COUNT(column):**排除該欄位為 NULL 的行**,統計非空值個數。

EXISTS 子查詢中的選擇

-- 推薦:語義明確,優化器可短路
SELECT * FROM orders o
WHERE EXISTS (SELECT 1 FROM order_items i WHERE i.order_id = o.order_id);

-- 不推薦:雖然結果相同,但語義模糊
SELECT * FROM orders o
WHERE EXISTS (SELECT * FROM order_items i WHERE i.order_id = o.order_id);

SELECT 1 / SELECT 'X' 在 EXISTS 中僅作「存在性檢查」,不涉及資料傳輸,效能最優。

延伸:SUM(1) 技巧

SELECT COUNT(*) FROM t WHERE cond;   -- 等價於
SELECT SUM(1) FROM t WHERE cond;     -- 可擴展:SUM(2) = 2 * 行數,SUM(-1) = -行數

調優檢查清單

  1. 確認表是否有主鍵/唯一索引 → 優先 COUNT(pk_col)
  2. 無索引且頻繁統計全表 → 建議建立計數表或使用 DBMS_STATS 近似值(NUM_ROWS)
  3. 避免在大表無索引欄位上做 COUNT(col)(需全表掃描+NULL 過濾)
  4. 檢查執行計畫:是否為 INDEX FAST FULL SCAN 或 TABLE ACCESS FULL

「COUNT(*) 慢」是過時經驗。現代優化器對 COUNT(*) 有專門優化(直接讀取段頭或索引統計),實務上**語義正確優於微觀優化**——該用 COUNT(*) 統計行數時就大方用,需要非空計數才用 COUNT(col)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved