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

MySQL DISTINCT 底層原理:鬆散/緊湊索引掃描、臨時表與 GROUP BY 關係

     編輯:MySQL 資料庫相關知識

通過 EXPLAIN 實測展示 DISTINCT 三種執行路徑:鬆散索引掃描、緊湊索引掃描、臨時表(無 filesort),並對比帶聚合函數時的 filesort 差異。

環境

CREATE TABLE group_message (
  group_id INT, user_id INT, gc INT,
  INDEX idx_gid_uid_gc (group_id, user_id, gc)
) ENGINE=InnoDB;

1. 鬆散索引掃描

EXPLAIN SELECT DISTINCT group_id FROM group_message;
-- Extra: Using index for group-by

利用複合索引首列 group_id 已排序特性,直接跳躍讀取每組第一筆,**無臨時表、無排序**。

2. 緊湊索引掃描

EXPLAIN SELECT DISTINCT user_id FROM group_message WHERE group_id = 2;
-- Extra: Using where; Using index

掃描 group_id=2 的所有索引鍵,利用索引有序性逐個讀取 user_id,值變化時保留一條。**同樣無臨時表、無排序**。

3. 臨時表(無法單靠索引完成)

EXPLAIN SELECT DISTINCT user_id FROM group_message WHERE group_id > 1 AND group_id < 10;
-- Extra: Using where; Using index; Using temporary

範圍查詢導致索引鍵不連續,需臨時表去重,**但無 Using filesort**,證明 MySQL 分組不強制排序。

4. 結合 GROUP BY + 聚合函數 → filesort

EXPLAIN SELECT DISTINCT MAX(user_id) FROM group_message
WHERE group_id > 1 AND group_id < 10 GROUP BY group_id;
-- Extra: Using where; Using index; Using temporary; Using filesort

MAX() 需取組內最大值,無索引支援只能排序產生 filesort。

DISTINCT vs GROUP BY 效能實測 (10 萬行)

場景DISTINCT 耗時GROUP BY 耗時結論
無索引~0.073s~0.073sDISTINCT 略快
加索引後~0.0024s~0.0011sGROUP BY 明顯更快

建議:大表關鍵字段務必加索引,索引後 GROUP BY 效能優勢明顯;無索引場景差異微小。

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