詳解MySQL中DISTINCT去重的核心注意事項(xiàng)
DISTINCT 六大注意事項(xiàng)
1. 作用范圍:所有 SELECT 字段
SELECT DISTINCT a, b FROM table; -- 對(duì)(a,b)組合整體去重
誤以為只作用于第一個(gè)字段:
-- 錯(cuò)誤理解:以為只對(duì)name去重 SELECT DISTINCT name, class FROM students;
實(shí)際效果:對(duì) (name, class) 組合去重(如 ('張三','一班') 和 ('張三','二班') 算不同記錄)
2. NULL 值的特殊處理
INSERT INTO students (name, class, score) VALUES (NULL, '三班', 90); ???????SELECT DISTINCT name FROM students;
結(jié)果:
+--------+
| name |
+--------+
| 張三 |
| 李四 |
| 王五 |
| NULL | -- NULL被視為獨(dú)立值保留
+--------+
3. 性能陷阱(大數(shù)據(jù)量)
-- 當(dāng)表有百萬(wàn)行時(shí)慎用 SELECT DISTINCT text_column FROM huge_table;
優(yōu)化方案:
-- 先通過(guò)WHERE縮小范圍再去重 SELECT DISTINCT text_column FROM huge_table WHERE create_time > '2023-01-01'; -- 或添加索引(對(duì)text類型有限制) ALTER TABLE huge_table ADD INDEX idx_text(text_column(20)); -- 前綴索引
4. 與 ORDER BY 的優(yōu)先級(jí)
SELECT DISTINCT class FROM students ORDER BY score DESC; -- 錯(cuò)誤!score不在SELECT中
正確寫(xiě)法:
-- 方案1:排序字段必須在SELECT中 SELECT DISTINCT class, MAX(score) AS max_score FROM students GROUP BY class ORDER BY max_score DESC; -- 方案2:子查詢 SELECT DISTINCT class FROM ( SELECT class, score FROM students ORDER BY score DESC ) AS tmp;
5. 聚合函數(shù)中的 DISTINCT
-- 統(tǒng)計(jì)不重復(fù)的班級(jí)數(shù)量 SELECT COUNT(DISTINCT class) FROM students; -- 錯(cuò)誤用法(語(yǔ)法無(wú)效): SELECT DISTINCT COUNT(class) FROM students;
6. 不可用于部分字段計(jì)算
-- 嘗試計(jì)算不同班級(jí)的平均分(錯(cuò)誤?。? SELECT DISTINCT class, AVG(score) FROM students;
正確做法:必須配合 GROUP BY
SELECT class, AVG(score) FROM students GROUP BY class; -- 這才是標(biāo)準(zhǔn)解法
高級(jí)注意點(diǎn)
7. 與 LIMIT 的配合問(wèn)題
SELECT DISTINCT class FROM students LIMIT 2;
結(jié)果不確定性:
返回的 2 條記錄是隨機(jī)的(除非指定 ORDER BY),不同執(zhí)行可能結(jié)果不同。
8. 臨時(shí)表空間占用
DISTINCT 操作會(huì)在內(nèi)存/磁盤(pán)創(chuàng)建臨時(shí)表存儲(chǔ)唯一值
當(dāng)去重字段總數(shù)據(jù)量超過(guò) tmp_table_size 時(shí),性能急劇下降
查看閾值:
SHOW VARIABLES LIKE 'tmp_table_size'; -- 默認(rèn)16MB
對(duì)比 GROUP BY 去重
| 特性 | DISTINCT | GROUP BY |
|---|---|---|
| 是否可搭配聚合函數(shù) | ? | ? (如SUM/AVG) |
| 結(jié)果排序 | 無(wú)序 | 可按分組鍵排序 |
| 執(zhí)行效率 | 簡(jiǎn)單場(chǎng)景更快 | 復(fù)雜聚合時(shí)更優(yōu) |
| 索引利用 | 可使用索引 | 必須用分組字段索引 |
最佳實(shí)踐總結(jié)
小數(shù)據(jù)量:直接 DISTINCT 簡(jiǎn)潔高效
需要聚合計(jì)算:用 GROUP BY 替代
精確去重計(jì)數(shù):優(yōu)先 COUNT(DISTINCT column)
排序需求:必須顯式寫(xiě) ORDER BY
超大數(shù)據(jù):先過(guò)濾再去重 + 合理索引
實(shí)戰(zhàn)檢驗(yàn)
訂單表 orders 結(jié)構(gòu):
CREATE TABLE orders (
id INT PRIMARY KEY,
product_id INT,
user_id INT,
amount DECIMAL(10,2),
coupon_code VARCHAR(20) -- 允許為NULL
);
問(wèn)題:
如何高效獲取使用過(guò)不同優(yōu)惠券的用戶ID列表(含NULL)?
寫(xiě)出你的解決方案:
SELECT _______________________________
FROM orders;
答案(折疊):
-- 方案1:基礎(chǔ)寫(xiě)法 SELECT DISTINCT user_id, coupon_code FROM orders WHERE coupon_code IS NOT NULL; -- 若需包含NULL則去掉WHERE ???????-- 方案2:大數(shù)據(jù)量?jī)?yōu)化(添加聯(lián)合索引) ALTER TABLE orders ADD INDEX idx_user_coupon(user_id, coupon_code); SELECT DISTINCT user_id, coupon_code FROM orders;
到此這篇關(guān)于詳解MySQL中DISTINCT去重的核心注意事項(xiàng)的文章就介紹到這了,更多相關(guān)MySQL DISTINCT去重內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL的時(shí)間差函數(shù)TIMESTAMPDIFF、DATEDIFF的用法
這篇文章主要介紹了MySQL的時(shí)間差函數(shù)TIMESTAMPDIFF、DATEDIFF的用法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
Mysql常見(jiàn)bug及解決方案超詳細(xì)講解
在使用MySQL的過(guò)程中,相比大家都踩過(guò)不少坑,下面這篇文章主要給大家介紹了關(guān)于Mysql常見(jiàn)bug及解決方案超詳細(xì)講解的相關(guān)資料,文中介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06
MySQL數(shù)據(jù)庫(kù)char與varchar的區(qū)別分析及使用建議
本文主要介紹了mysql中VARCHAR與CHAR字符型數(shù)據(jù)的差異以及這兩種字符型數(shù)據(jù)在項(xiàng)目中的使用建議,真心不錯(cuò)。值得一看。小編有種受益匪淺的感覺(jué)。2014-09-09
Mysqlslap MySQL壓力測(cè)試工具 簡(jiǎn)單教程
Mysqlslap是從5.1.4版開(kāi)始的一個(gè)MySQL官方提供的壓力測(cè)試工具。通過(guò)模擬多個(gè)并發(fā)客戶端訪問(wèn)MySQL來(lái)執(zhí)行壓力測(cè)試,同時(shí)詳細(xì)的提供了“高負(fù)荷攻擊MySQL”的數(shù)據(jù)性能報(bào)告。并且能很好的對(duì)比多個(gè)存儲(chǔ)引擎在相同環(huán)境下的并發(fā)壓力性能差別2011-10-10
如何解決mysql出現(xiàn)Incorrect string value for co
這篇文章主要介紹了如何解決mysql出現(xiàn)Incorrect string value for column ‘表項(xiàng)‘ at row 1錯(cuò)誤問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-03-03
登錄mysql時(shí)出現(xiàn)的閃退問(wèn)題解決
大家在打開(kāi)MySQL時(shí),可能會(huì)遇到在登陸界面輸入密碼之后就閃退的這個(gè)問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于如何解決登錄mysql時(shí)出現(xiàn)的閃退問(wèn)題的相關(guān)資料,需要的朋友可以參考下2023-05-05
解決MySQL安裝重裝時(shí)出現(xiàn)could not start the service mysql error:0問(wèn)題的方法
這篇文章主要為大家詳細(xì)介紹了解決MySQL安裝重裝時(shí)出現(xiàn)could not start the service mysql error:0問(wèn)題的方法,感興趣的小伙伴們可以參考一下2016-06-06
MySQL 8.0.18給數(shù)據(jù)庫(kù)添加用戶和賦權(quán)問(wèn)題
這篇文章主要介紹了MySQL 8.0.18給數(shù)據(jù)庫(kù)添加用戶和賦權(quán)問(wèn)題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12

