測試環境
- 表結構:
id PK, num INT,MyISAM 引擎
- 數據量:10 萬行,
num 隨機 0-100
- 工具:命令行
SET PROFILING=1 + SHOW PROFILES
測試場景與結果
| 場景 | SQL | 耗時 (ms) | 說明 |
| 無索引 | SELECT DISTINCT num FROM test_test | 0.078 | 全表掃描 + 臨時表去重 |
SELECT num FROM test_test GROUP BY num | 0.031 | 全表掃描 + 排序去重,較快 |
| 建立 idx_num | SELECT DISTINCT num FROM test_test | 0.000725 | 索引全掃描,快 107 倍 |
SELECT num FROM test_test GROUP BY num | 0.000716 | 索引全掃描,快 43 倍 |
核心結論
- 有無索引下 GROUP BY 均快於 DISTINCT(約 2-2.5 倍)
- 索引對兩者提升巨大,但 GROUP BY 受益相對更大
- MySQL 優化器將
DISTINCT 內部轉換為 GROUP BY 執行,額外轉換開銷導致略慢
實戰建議
- 去重查詢優先使用 GROUP BY
- 確保去重欄位建立索引
- 僅需計數時:
COUNT(DISTINCT col) 仍可用,但大數據量建議改用子查詢 SELECT COUNT(*) FROM (SELECT col FROM t GROUP BY col) t2
擴展驗證
EXPLAIN SELECT DISTINCT num FROM test_test;
EXPLAIN SELECT num FROM test_test GROUP BY num;
-- 兩者 Extra 均顯示 "Using index",但 GROUP BY 無 "Using temporary"