目錄
distinct的使用
distinct用法
distinct 多列去重
group by的使用
單一列去重
多列去重
區別範例
distinct和group by原理
隱含排序
首頁 資料庫 mysql教程 MySQL中的distinct與group by如何使用

MySQL中的distinct與group by如何使用

May 26, 2023 am 10:34 AM
mysql distinct group by

    先說大致的結論:

    • 在語意相同,有索引的情況:group bydistinct 都能使用索引,效率相同。

    • 在語意相同,無索引的情況下:distinct 效率高於group by。原因是 distinct 和 group by都會進行分組操作,但group by可能會進行排序,觸發 filesort,導致 sql 執行效率低下。

    基於這個結論,你可能會問:

    • 為什麼在語意相同,有索引的情況下,group bydistinct 效率相同?

    • 在什麼情況下,group by會進行排序運算?

    帶著這兩個問題找出答案。接下來,我們先來看看 distinctgroup by的基礎使用。

    distinct的使用

    distinct用法

    SELECT DISTINCT columns FROM table_name WHERE where_conditions;
    登入後複製

    例如:

    mysql> select distinct age from student;
    +------+
    | age  |
    +------+
    |   10 |
    |   12 |
    |   11 |
    | NULL |
    +------+
    4 rows in set (0.01 sec)
    登入後複製

    DISTINCT 關鍵字用於傳回唯一不同的值。放在查詢語句中的第一個欄位前使用,並作用於主句所有欄位。

    如果欄位具有NULL 值,並且對這個欄位使用DISTINCT子句,MySQL 將保留一個NULL 值,並刪除其它的NULL 值,因為DISTINCT子句將所有NULL 值視為相同的值。

    distinct 多列去重

    distinct 多列的去重,則是根據指定的去重的列信息來進行,即只有所有指定的列信息都相同,才會被認為是重複的訊息。

    SELECT DISTINCT column1,column2 FROM table_name WHERE where_conditions;
    mysql> select distinct sex,age from student;
    +--------+------+
    | sex    | age  |
    +--------+------+
    | male   |   10 |
    | female |   12 |
    | male   |   11 |
    | male   | NULL |
    | female |   11 |
    +--------+------+
    5 rows in set (0.02 sec)
    登入後複製

    group by的使用

    對於基礎去重來說,group by 的使用和 distinct 類似。

    單一列去重

    語法:

    SELECT columns FROM table_name WHERE where_conditions GROUP BY columns;
    登入後複製
    登入後複製

    執行:

    mysql> select age from student group by age;
    +------+
    | age  |
    +------+
    |   10 |
    |   12 |
    |   11 |
    | NULL |
    +------+
    4 rows in set (0.02 sec)
    登入後複製

    多列去重

    語法:

    SELECT columns FROM table_name WHERE where_conditions GROUP BY columns;
    登入後複製
    登入後複製

    執行:

    mysql> select sex,age from student group by sex,age;
    +--------+------+
    | sex    | age  |
    +--------+------+
    | male   |   10 |
    | female |   12 |
    | male   |   11 |
    | male   | NULL |
    | female |   11 |
    +--------+------+
    5 rows in set (0.03 sec)
    登入後複製

    區別範例

    兩者的語法差異在於,group by可以進行單列去重,group by的原理是先將結果分組排序,然後傳回每組中的第一筆資料。並且是根據group by的後接字段進行去重的。

    例如:

    mysql> select sex,age from student group by sex;
    +--------+-----+
    | sex    | age |
    +--------+-----+
    | male   |  10 |
    | female |  12 |
    +--------+-----+
    2 rows in set (0.03 sec)
    登入後複製

    distinct和group by原理

    在大多數例子中,DISTINCT可以被看作是特殊的GROUP BY,它們的實作都基於分組操作,且都可以透過鬆散索引掃描、緊湊索引掃描(關於索引掃描的內容會在其他文章中詳細介紹,就不在此細緻介紹了)來實現。

    DISTINCTGROUP BY都是可以使用索引進行掃描搜尋的。例如以下兩個sql(只單單看表格最後extra 的內容),我們對這兩個sql 進行分析,可以看到,在extra 中,這兩個sql 都使用了緊湊索引掃描Using index for group -by

    所以,在一般情況下,對於相同語意的DISTINCTGROUP BY語句,我們可以對其使用相同的索引最佳化手段來進行最佳化。

    mysql> explain select int1_index from test_distinct_groupby group by int1_index;
    +----+-------------+-----------------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
    | id | select_type | table                 | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra                    |
    +----+-------------+-----------------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
    |  1 | SIMPLE      | test_distinct_groupby | NULL       | range | index_1       | index_1 | 5       | NULL |  955 |   100.00 | Using index for group-by |
    +----+-------------+-----------------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
    1 row in set (0.05 sec)
    mysql> explain select distinct int1_index from test_distinct_groupby;
    +----+-------------+-----------------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
    | id | select_type | table                 | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra                    |
    +----+-------------+-----------------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
    |  1 | SIMPLE      | test_distinct_groupby | NULL       | range | index_1       | index_1 | 5       | NULL |  955 |   100.00 | Using index for group-by |
    +----+-------------+-----------------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
    1 row in set (0.05 sec)
    登入後複製

    但對於GROUP BY來說,在 MYSQL8.0 之前,GROUP Y預設會依據欄位進行隱含排序。

    可以看到,下面這條 sql 語句在使用了暫存資料表的同時,也進行了 filesort。

    mysql> explain select int6_bigger_random from test_distinct_groupby GROUP BY int6_bigger_random;
    +----+-------------+-----------------------+------------+------+---------------+------+---------+------+-------+----------+---------------------------------+
    | id | select_type | table                 | partitions | type | possible_keys | key  | key_len | ref  | rows  | filtered | Extra                           |
    +----+-------------+-----------------------+------------+------+---------------+------+---------+------+-------+----------+---------------------------------+
    |  1 | SIMPLE      | test_distinct_groupby | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 97402 |   100.00 | Using temporary; Using filesort |
    +----+-------------+-----------------------+------------+------+---------------+------+---------+------+-------+----------+---------------------------------+
    1 row in set (0.04 sec)
    登入後複製

    隱含排序

    對於隱含排序,我們可以參考MySQL 官方的解釋:

    https://dev.mysql.com/doc/refman/5.7 /en/order-by-optimization.html

    GROUP BY implicitly sorts by default (that is, in the absence of ASC or DESC designators for GROUP BY columns). However, relying on implicit GROlumns). However, relying on implicit GROlumns). However, relying on implicit GROlumns). However, relying on implicit GROlumns). However, relying on implicit GROlumns). However, relying on implicit GROlumns sorting (that is, sorting in the absence of ASC or DESC designators) or explicit sorting for GROUP BY (that is, by using explicit ASC or DESC designators for GROUP BY columns) is precated.Tod dcatcated. BY clause.

    大致解釋一下:

    GROUP BY 預設隱含排序(指在GROUP BY 欄位沒有ASC 或DESC 指示符的情況下也會進行排序)。然而,GROUP BY 進行明確或隱式排序已經過時(deprecated)了,要產生給定的排序順序,請提供 ORDER BY 子句。

    所以,在 MySQL8.0 之前,GROUP BY會預設根據作用欄位(GROUP BY的後接欄位)對結果進行排序。在能利用索引的情況下,GROUP BY不需要額外進行排序操作;但當無法利用索引排序時,MySQL 優化器就必須選擇透過使用臨時表然後再排序的方式來實現GROUP BY了。

    且當結果集的大小超出系統設定臨時表大小時,MySQL 會將臨時表資料 copy 到磁碟上面再進行操作,語句的執行效率會變得極低。這也是 MySQL 選擇將此操作(隱式排序)棄用的原因。

    基於上述原因,Mysql 在 8.0 時,對此進行了最佳化更新:

    https://dev.mysql.com/doc/refman/8.0/en/order-by-optimization.html

    Previously (MySQL 5.7 and lower), GROUP BY sorted implicitly under certain conditions. In MySQL 8.0, that no longer occurs, so specifying ORDER BY NULL at the end to suppress implicit sorting (as was done previously) is no longer necessary. However, query results may dven er from lover query results may yh. sort order, provide an ORDER BY clause.

    大致解釋一下:

    從前(MySQL5.7 版本之前),Group by 會根據確定的條件進行隱含排序。在 MySQL 8.0 中,已經移除了這個功能,所以不再需要透過新增order by null 來禁止隱式排序了,但是,查詢結果可能與先前的 MySQL 版本不同。若要產生給定順序的結果,請按透過ORDER BY指定需要進行排序的欄位。

    因此,我們的結論也出來了:

    • 在語意相同,有索引的情況下: group bydistinct 都能使用索引,效率相同。因為group bydistinct近乎等價,distinct 可以被看做是特殊的group by

    • 在語意相同,無索引的情況下: distinct 效率高於group by。原因是distinctgroup by都會進行分組操作,但group by在MySQL8.0 之前會進行隱含排序,導致觸發filesort,sql 執行效率低下。但從MySQL8.0 開始,MySQL 就刪除了隱含排序,所以,此時在語意相同,無索引的情況下,group bydistinct的執行效率也是近乎等價的。

    比起distinct來說,group by的語意明確。且由於distinct 關鍵字會對所有欄位生效,在進行複合業務處理時,group by的使用彈性更高,group by能根據分組情況,對資料進行更為複雜的處理,例如透過having對資料進行過濾,或透過聚合函數對資料進行運算。

    以上是MySQL中的distinct與group by如何使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    本網站聲明
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

    熱AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智慧驅動的應用程序,用於創建逼真的裸體照片

    AI Clothes Remover

    AI Clothes Remover

    用於從照片中去除衣服的線上人工智慧工具。

    Undress AI Tool

    Undress AI Tool

    免費脫衣圖片

    Clothoff.io

    Clothoff.io

    AI脫衣器

    AI Hentai Generator

    AI Hentai Generator

    免費產生 AI 無盡。

    熱門文章

    R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
    1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.最佳圖形設置
    1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
    威爾R.E.P.O.有交叉遊戲嗎?
    1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

    熱工具

    記事本++7.3.1

    記事本++7.3.1

    好用且免費的程式碼編輯器

    SublimeText3漢化版

    SublimeText3漢化版

    中文版,非常好用

    禪工作室 13.0.1

    禪工作室 13.0.1

    強大的PHP整合開發環境

    Dreamweaver CS6

    Dreamweaver CS6

    視覺化網頁開發工具

    SublimeText3 Mac版

    SublimeText3 Mac版

    神級程式碼編輯軟體(SublimeText3)

    mysql:簡單的概念,用於輕鬆學習 mysql:簡單的概念,用於輕鬆學習 Apr 10, 2025 am 09:29 AM

    MySQL是一個開源的關係型數據庫管理系統。 1)創建數據庫和表:使用CREATEDATABASE和CREATETABLE命令。 2)基本操作:INSERT、UPDATE、DELETE和SELECT。 3)高級操作:JOIN、子查詢和事務處理。 4)調試技巧:檢查語法、數據類型和權限。 5)優化建議:使用索引、避免SELECT*和使用事務。

    phpmyadmin怎麼打開 phpmyadmin怎麼打開 Apr 10, 2025 pm 10:51 PM

    可以通過以下步驟打開 phpMyAdmin:1. 登錄網站控制面板;2. 找到並點擊 phpMyAdmin 圖標;3. 輸入 MySQL 憑據;4. 點擊 "登錄"。

    MySQL:世界上最受歡迎的數據庫的簡介 MySQL:世界上最受歡迎的數據庫的簡介 Apr 12, 2025 am 12:18 AM

    MySQL是一種開源的關係型數據庫管理系統,主要用於快速、可靠地存儲和檢索數據。其工作原理包括客戶端請求、查詢解析、執行查詢和返回結果。使用示例包括創建表、插入和查詢數據,以及高級功能如JOIN操作。常見錯誤涉及SQL語法、數據類型和權限問題,優化建議包括使用索引、優化查詢和分錶分區。

    為什麼要使用mysql?利益和優勢 為什麼要使用mysql?利益和優勢 Apr 12, 2025 am 12:17 AM

    選擇MySQL的原因是其性能、可靠性、易用性和社區支持。 1.MySQL提供高效的數據存儲和檢索功能,支持多種數據類型和高級查詢操作。 2.採用客戶端-服務器架構和多種存儲引擎,支持事務和查詢優化。 3.易於使用,支持多種操作系統和編程語言。 4.擁有強大的社區支持,提供豐富的資源和解決方案。

    redis怎麼使用單線程 redis怎麼使用單線程 Apr 10, 2025 pm 07:12 PM

    Redis 使用單線程架構,以提供高性能、簡單性和一致性。它利用 I/O 多路復用、事件循環、非阻塞 I/O 和共享內存來提高並發性,但同時存在並發性受限、單點故障和不適合寫密集型工作負載的局限性。

    MySQL和SQL:開發人員的基本技能 MySQL和SQL:開發人員的基本技能 Apr 10, 2025 am 09:30 AM

    MySQL和SQL是開發者必備技能。 1.MySQL是開源的關係型數據庫管理系統,SQL是用於管理和操作數據庫的標準語言。 2.MySQL通過高效的數據存儲和檢索功能支持多種存儲引擎,SQL通過簡單語句完成複雜數據操作。 3.使用示例包括基本查詢和高級查詢,如按條件過濾和排序。 4.常見錯誤包括語法錯誤和性能問題,可通過檢查SQL語句和使用EXPLAIN命令優化。 5.性能優化技巧包括使用索引、避免全表掃描、優化JOIN操作和提升代碼可讀性。

    MySQL的位置:數據庫和編程 MySQL的位置:數據庫和編程 Apr 13, 2025 am 12:18 AM

    MySQL在數據庫和編程中的地位非常重要,它是一個開源的關係型數據庫管理系統,廣泛應用於各種應用場景。 1)MySQL提供高效的數據存儲、組織和檢索功能,支持Web、移動和企業級系統。 2)它使用客戶端-服務器架構,支持多種存儲引擎和索引優化。 3)基本用法包括創建表和插入數據,高級用法涉及多表JOIN和復雜查詢。 4)常見問題如SQL語法錯誤和性能問題可以通過EXPLAIN命令和慢查詢日誌調試。 5)性能優化方法包括合理使用索引、優化查詢和使用緩存,最佳實踐包括使用事務和PreparedStatemen

    怎樣建立sql數據庫 怎樣建立sql數據庫 Apr 09, 2025 pm 04:24 PM

    構建 SQL 數據庫涉及 10 個步驟:選擇 DBMS;安裝 DBMS;創建數據庫;創建表;插入數據;檢索數據;更新數據;刪除數據;管理用戶;備份數據庫。

    See all articles