萬盛學電腦網

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

SQL DISTINCT 去重完全指南:語法、多列、性能、替代方案

一條關鍵字搞定行級去重,但別濫用

DISTINCT 作用於 SELECT 列表,將結果集中所有列值完全相同的行合併為一行。本文解析單列/多列去重、與 GROUP BY 關係、性能影響、大數據替代方案。

語法與基本用法

SELECT DISTINCT column_name FROM table WHERE condition;
SELECT DISTINCT col1, col2, col3 FROM table;

單列 vs 多列去重

查詢去重維度結果行特徵
DISTINCT citycitycity 唯一
DISTINCT city, state(city, state) 元組city+state 組合唯一
DISTINCT *所有列整行唯一

實例

-- 僅返回唯一姓氏
SELECT DISTINCT OwnerLastName FROM AntiqueOwners;

-- 返回唯一 城市-州 組合
SELECT DISTINCT City, State FROM EmployeeAddressTable;

DISTINCT vs GROUP BY

特性DISTINCTGROUP BY
語義結果集去重分組聚合
可用聚合函數否是
排序保證無(實現常排序)無(需 ORDER BY)
性能臨時表/排序去重可走索引掃描
擴展性弱強(HAVING、ROLLUP、窗口函數)

💡 等價轉換:SELECT DISTINCT a,b FROM t ≡ SELECT a,b FROM t GROUP BY a,b

性能與優化

  • 會產生臨時表:Using temporary,大結果集極慢
  • 索引優化:INDEX (col1, col2) 可支援 DISTINCT col1, col2 索引全掃描去重
  • 早期過濾:先 WHERE 裁剪再 DISTINCT
  • 只取需求列:SELECT DISTINCT * 極其低效

大數據替代方案

  1. 近似去重:APPROX_COUNT_DISTINCT(col) (MySQL 8.0.11+),誤差 < 1%,毫秒級
  2. 物化視圖/匯總表:定時任務預計算去重結果
  3. 應用層去重:流式處理中用 Bloom Filter / HyperLogLog
  4. 分區表:按時間分區,分區內去重再合併

避坑清單

  1. DISTINCT 只能出現一次,SELECT DISTINCT a, DISTINCT b 語法錯誤
  2. COUNT(DISTINCT col) 統計非空唯一值,COUNT(*) 統計行數
  3. 隱式排序不保證:需穩定順序請加 ORDER BY
  4. JSON/TEXT/BLOB 列不可直接 DISTINCT,需轉換或哈希

總結

小結果集用 DISTINCT 簡潔;
需聚合指標用 GROUP BY;
大數據用近似算法或預聚合;
索引支撐去重列最關鍵。

copyright © 萬盛學電腦網 all rights reserved