首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 索引優化 DISTINCT 查詢與多欄位去重解決方案

     編輯:MySQL 資料庫相關知識

探討 DISTINCT 能否利用索引優化,發現 **索引類型(BTREE vs HASH)是關鍵**;並提供 3 種多欄位去重替代寫法。

案例 1:InnoDB + BTREE 主鍵 → 索引生效

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  ✅

案例 2:MEMORY + 預設 HASH 主鍵 → 索引失效

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 需全表掃描。

案例 3:MEMORY + 顯式 BTREE 索引 → 索引生效

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  ✅

核心結論

  • HASH 索引:適合等值查找,**不支援範圍/排序/分組** 操作(DISTINCT、GROUP BY、ORDER BY)。
  • BTREE 索引:支援有序操作,**DISTINCT/GROUP BY/ORDER BY 才能用上索引**。
  • 查詢計劃顯示 type=ALL 時,**先檢查索引類型** 是否為 HASH。

DISTINCT 多欄位去重 3 種寫法

需求:去重 title 並保留對應 posttime。

  1. 子查詢取最小 ID(推薦,語義清晰)
SELECT title, posttime FROM table1
WHERE id IN (SELECT MIN(id) FROM table1 GROUP BY title);
  1. GROUP BY 多欄位
SELECT title, posttime FROM table1 GROUP BY title, posttime;
  1. DISTINCT + 欄位列表(僅當所有列組合唯一時等價)
SELECT DISTINCT title, posttime FROM table1;

選擇建議:方案 1 保留每組第一筆(可控);方案 2/3 保留所有唯一組合,語義不同,視業務而定。

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