萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

SQL SELECT DISTINCT 完全指南:去重原理、性能、多列、與 GROUP BY 對比

語法

SELECT DISTINCT column_list FROM table_name [WHERE ...];

核心行為

  • 對 結果集投影列 進行整行去重
  • DISTINCT col1, col2 ≠ DISTINCT col1 + DISTINCT col2,而是 (col1, col2) 元組去重
  • NULL 視為相同值(所有 NULL 視為一組)
  • 可與聚合函數共用:COUNT(DISTINCT col)

示例數據

CREATE TABLE `orders` (
    `id` INT PRIMARY KEY,
    `customer` VARCHAR(20),
    `product` VARCHAR(20),
    `amount` DECIMAL(10,2)
);
INSERT INTO `orders` VALUES
(1, 'Alice', 'Apple', 10),
(2, 'Alice', 'Banana', 20),
(3, 'Bob',   'Apple', 15),
(4, 'Alice', 'Apple', 10);  -- 完全重複行

各類去重效果

查詢結果行數說明
SELECT DISTINCT customer FROM orders2Alice, Bob
SELECT DISTINCT customer, product FROM orders3(Alice,Apple), (Alice,Banana), (Bob,Apple)
SELECT DISTINCT * FROM orders3第 4 行與第 1 行完全相同被去重
SELECT COUNT(DISTINCT customer) FROM orders1 行,值=2聚合去重計數

DISTINCT vs GROUP BY

維度DISTINCTGROUP BY
語義結果集去重分組聚合
可用聚合函數不可(除 COUNT(DISTINCT))可(SUM, AVG, MAX 等)
排序無保證(實現常排序)無保證(需 ORDER BY)
性能相同(內部同樣用臨時表/排序去重)相同
擴展性單純去重支持 HAVING、WITH ROLLUP、窗口函數

性能優化

  1. 只選必要列:列越多,比較/排序/臨時表越大
  2. 去重列加索引:INDEX (customer, product) 可避免臨時表(Index Full Scan + 去重)
  3. 大表分批:INSERT INTO tmp SELECT DISTINCT ... FROM big_table LIMIT 100000 循環
  4. 近似去重:HyperLogLog (Redis) / APPROX_COUNT_DISTINCT (8.0.13+)

實戰場景

1. 統計 UV(獨立訪客)

-- 精確
SELECT COUNT(DISTINCT user_id) FROM page_views WHERE date = '2024-01-15';

-- 近似(百萬級以上,誤差 < 2%)
SELECT APPROX_COUNT_DISTINCT(user_id) FROM page_views WHERE date = '2024-01-15';

2. 獲取不重複的標籤列表

SELECT DISTINCT tag FROM article_tags ORDER BY tag;

3. 找出重複數據(反向)

SELECT customer, product, COUNT(*) AS cnt
FROM orders
GROUP BY customer, product
HAVING COUNT(*) > 1;

常見誤區

誤區真相
DISTINCT 加快查詢增加去重開銷,僅在需去重時使用
DISTINCT 只對第一列生效對 SELECT 列表所有列組合去重
DISTINCT 可用於單列並保留其他列原值不可,需配合 GROUP BY 或窗口函數
SELECT DISTINCT a, b 等價於 SELECT a, b GROUP BY a, b結果相同,但 GROUP BY 可加聚合、HAVING、ROLLUP

MySQL 8.0 新特性

  • APPROX_COUNT_DISTINCT(expr):近似計數,極快,適合大數據儀表盤
  • DISTINCT 內部優化:優先嘗試 Loose Index Scan(鬆散索引掃描)避免臨時表
  • CTE + 窗口函數替代複雜 DISTINCT 邏輯
copyright © 萬盛學電腦網 all rights reserved