網路上流傳「COUNT(1) 比 COUNT(*) 快」,實際情況取決於**表結構與執行計畫**。
| 場景 | 最快寫法 | 說明 |
|---|---|---|
| 表**無主鍵** | COUNT(1) | 全表掃描時,1 為常數不需讀取行資料,略快於 *(需展開所有欄位元數據) |
| 表**有主鍵** | COUNT(主鍵欄位) | 優化器可直接掃描主鍵索引(通常較窄),避免全表掃描 |
| 表**只有一個欄位** | COUNT(*) | 無額外開銷,語義最清晰 |
COUNT(*)、COUNT(1)、COUNT(常數):**包含 NULL 行**,統計滿足 WHERE 條件的**行數**。COUNT(column):**排除該欄位為 NULL 的行**,統計非空值個數。-- 推薦:語義明確,優化器可短路
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 中僅作「存在性檢查」,不涉及資料傳輸,效能最優。
SELECT COUNT(*) FROM t WHERE cond; -- 等價於
SELECT SUM(1) FROM t WHERE cond; -- 可擴展:SUM(2) = 2 * 行數,SUM(-1) = -行數
COUNT(pk_col)DBMS_STATS 近似值(NUM_ROWS)COUNT(col)(需全表掃描+NULL 過濾)INDEX FAST FULL SCAN 或 TABLE ACCESS FULL「COUNT(*) 慢」是過時經驗。現代優化器對
COUNT(*)有專門優化(直接讀取段頭或索引統計),實務上**語義正確優於微觀優化**——該用COUNT(*)統計行數時就大方用,需要非空計數才用COUNT(col)。