探討 DISTINCT 能否利用索引優化,發現 **索引類型(BTREE vs HASH)是關鍵**;並提供 3 種多欄位去重替代寫法。
CREATE TABLE m11 (a INT PRIMARY KEY, b INT, c INT, d INT) ENGINE=InnoDB; EXPLAIN SELECT DISTINCT a FROM m11; -- type=index, key=PRIMARY, Extra=Using index ✅
CREATE TABLE m31 (a INT PRIMARY KEY, b INT, c INT, d INT) ENGINE=MEMORY; EXPLAIN SELECT DISTINCT a FROM m31; -- type=ALL, key=NULL ❌
MEMORY 預設 HASH 索引不支援有序掃描,DISTINCT 需全表掃描。
CREATE TABLE m33 (a INT, b INT, c INT, d INT, INDEX USING BTREE (a)) ENGINE=MEMORY; EXPLAIN SELECT DISTINCT a FROM m33; -- type=index, key=a ✅
DISTINCT、GROUP BY、ORDER BY)。type=ALL 時,**先檢查索引類型** 是否為 HASH。需求:去重 title 並保留對應 posttime。
SELECT title, posttime FROM table1 WHERE id IN (SELECT MIN(id) FROM table1 GROUP BY title);
SELECT title, posttime FROM table1 GROUP BY title, posttime;
SELECT DISTINCT title, posttime FROM table1;
選擇建議:方案 1 保留每組第一筆(可控);方案 2/3 保留所有唯一組合,語義不同,視業務而定。