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

MySQL DISTINCT vs GROUP BY 性能實測:索引加持下 GROUP BY 完勝

     編輯:MySQL 資料庫相關知識

實測環境

  • 數據量:10 萬行
  • 測試欄位:num INT(重複度高)
  • MySQL 版本:5.6+

測試過程

1. 建表與數據準備

CREATE TABLE test_test (
    id INT(11) NOT NULL AUTO_INCREMENT,
    num INT(11) NOT NULL DEFAULT 0,
    PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- 存儲過程批量插入 10 萬條隨機數
DELIMITER //
CREATE PROCEDURE p_test(pa INT)
BEGIN
    DECLARE i INT DEFAULT 0;
    DECLARE rand_num INT;
    WHILE i < pa DO
        SELECT CAST(RAND()*100 AS UNSIGNED) INTO rand_num;
        INSERT INTO test_test(num) VALUES (rand_num);
        SET i = i + 1;
    END WHILE;
END//
DELIMITER ;

CALL p_test(100000);

2. 無索引場景測試

SELECT DISTINCT num FROM test_test;
SELECT num FROM test_test GROUP BY num;

結果:GROUP BY 快約 2 倍(MyISAM 全表掃描+臨時表排序,GROUP BY 內部優化更好)

3. 加索引後測試

ALTER TABLE test_test ADD INDEX num_index (num);

-- 命令行開啟 Profiling 精確測量
SET PROFILING=1;
SELECT DISTINCT num FROM test_test;
SELECT num FROM test_test GROUP BY num;
SHOW PROFILES;

結果(微秒級):

查詢耗時提升倍數
DISTINCT (無索引)~78ms基準
GROUP BY (無索引)~38ms2.05x
DISTINCT (有索引)~0.73ms107x
GROUP BY (有索引)~0.72ms53x

核心結論

  1. 有無索引差異巨大:索引將去重查詢提速 40-100 倍
  2. GROUP BY 持續優於 DISTINCT:無論是否有索引,GROUP BY 略快或持平
  3. 內部機制:MySQL 優化器會將 DISTINCT 轉換為 GROUP BY 執行,但轉換過程有微小開銷

最佳實踐建議

-- 推薦寫法:語義清晰、性能最優
SELECT num FROM test_test GROUP BY num;

-- 需要聚合統計時
SELECT num, COUNT(*) FROM test_test GROUP BY num;

-- 避免寫法
SELECT DISTINCT num FROM test_test;  -- 同義但略慢

擴展:EXPLAIN 驗證

EXPLAIN SELECT DISTINCT num FROM test_test;
EXPLAIN SELECT num FROM test_test GROUP BY num;

兩者 Extra 欄均顯示 Using index(走覆蓋索引),type=index,執行計劃幾乎一致。


實測證明:去重查詢首選 GROUP BY,並務必在去重欄位建立索引。這是性能優化中投入產出比最高的操作之一。

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