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

Oracle COUNT(*) vs COUNT(1) vs COUNT(欄位) 效能真相與適用場景

     編輯:Oracle 教學

Oracle COUNT(*) vs COUNT(1) vs COUNT(欄位) 效能真相與適用場景

關於 COUNT(*)、COUNT(1)、COUNT(欄位) 效能差異的討論由來已久。本文釐清迷思,給出實測依據的最佳選擇指南。

核心結論

寫法統計範圍效能排序適用場景
COUNT(*)所有列,含 NULL 列有主鍵時最快通用、有主鍵表
COUNT(1)常數 1,等同 COUNT(*)無主鍵時較快無主鍵表、Exists 子查詢
COUNT(欄位)該欄位非 NULL 值最慢(需判斷 NULL)需排除 NULL 統計

詳細規則

  1. 有主鍵(Primary Key):COUNT(主鍵) = COUNT(*) = COUNT(1),優化器自動轉為掃描主鍵索引,**最快**
  2. 無主鍵:COUNT(1) 略快於 COUNT(*)(避免展開 * 解析),但差異微乎其微
  3. 單欄位表:COUNT(*) 最快
  4. NULL 處理:COUNT(*)/COUNT(1) 統計所有列;COUNT(col) **不統計 NULL**

SELECT 1 vs SELECT * 效能差異

  • SELECT 1 FROM ...:回傳常數,僅判斷是否存在行(如 EXISTS 子查詢)
  • SELECT * FROM ...:回傳所有欄位
  • 有索引覆蓋 WHERE 條件時,SELECT 1 避免回表,**明顯較快**

SUM(1) 妙用

SELECT COUNT(*) FROM t WHERE cond;   -- 等同
SELECT SUM(1) FROM t WHERE cond;      -- 同樣結果

-- SUM 可傳任意數值
SELECT SUM(5) FROM t WHERE cond;      -- 回傳 5 * 滿足條件行數
SELECT SUM(-1) FROM t WHERE cond;     -- 回傳 -1 * 行數

實測建議

  1. 現代 Oracle (10g+) 優化器極其智慧,**COUNT(*) 與 COUNT(1) 執行計畫通常完全相同**
  2. 關鍵在於 **有無索引、統計資訊是否最新**、WHERE 條件能否走索引
  3. 習慣用 COUNT(*) 即可,語意最清晰,ANSI 標準
  4. 需排除 NULL 才用 COUNT(欄位)

延伸:大表快速估算行數

-- 從統計資訊取得估算值(極快,不掃表)
SELECT NUM_ROWS FROM USER_TABLES WHERE TABLE_NAME = 'BIG_TABLE';

-- 或查詢區塊層級估算
SELECT BLOCKS * AVG_ROW_LEN FROM USER_TABLES WHERE TABLE_NAME = 'BIG_TABLE';
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved