chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

為什么在語義相同的情況下group by和distinct效率相同呢?

jf_ro2CN3Fa ? 來源:CSDN ? 2023-01-09 10:46 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

結(jié)論

先說大致的結(jié)論:

在語義相同,有索引的情況下:group by和distinct都能使用索引,效率相同。

在語義相同,無索引的情況下:distinct效率高于group by。原因是distinct 和 group by都會進(jìn)行分組操作,但group by可能會進(jìn)行排序,觸發(fā)filesort,導(dǎo)致sql執(zhí)行效率低下。

基于這個結(jié)論,你可能會問:

為什么在語義相同,有索引的情況下,group by和distinct效率相同?

在什么情況下,group by會進(jìn)行排序操作?

帶著這兩個問題找答案。接下來,我們先來看一下distinct和group by的基礎(chǔ)使用。

基于 Spring Boot + MyBatis Plus + Vue & Element 實現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

distinct的使用

distinct用法

SELECTDISTINCTcolumnsFROMtable_nameWHEREwhere_conditions;

例如:

mysql>selectdistinctagefromstudent;
+------+
|age|
+------+
|10|
|12|
|11|
|NULL|
+------+
4rowsinset(0.01sec)

DISTINCT 關(guān)鍵詞用于返回唯一不同的值。放在查詢語句中的第一個字段前使用,且作用于主句所有列。

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

distinct多列去重

distinct多列的去重,則是根據(jù)指定的去重的列信息來進(jìn)行,即只有所有指定的列信息都相同,才會被認(rèn)為是重復(fù)的信息。

SELECTDISTINCTcolumn1,column2FROMtable_nameWHEREwhere_conditions;
mysql>selectdistinctsex,agefromstudent;
+--------+------+
|sex|age|
+--------+------+
|male|10|
|female|12|
|male|11|
|male|NULL|
|female|11|
+--------+------+
5rowsinset(0.02sec)

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實現(xiàn)的后臺管理系統(tǒng) + 用戶小程序,支持 RBAC 動態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

group by的使用

對于基礎(chǔ)去重來說,group by的使用和distinct類似:

單列去重

語法:

SELECTcolumnsFROMtable_nameWHEREwhere_conditionsGROUPBYcolumns;

執(zhí)行:

mysql>selectagefromstudentgroupbyage;
+------+
|age|
+------+
|10|
|12|
|11|
|NULL|
+------+
4rowsinset(0.02sec)

多列去重

語法:

SELECTcolumnsFROMtable_nameWHEREwhere_conditionsGROUPBYcolumns;

執(zhí)行:

mysql>selectsex,agefromstudentgroupbysex,age;
+--------+------+
|sex|age|
+--------+------+
|male|10|
|female|12|
|male|11|
|male|NULL|
|female|11|
+--------+------+
5rowsinset(0.03sec)

區(qū)別示例

兩者的語法區(qū)別在于,group by可以進(jìn)行單列去重,group by的原理是先對結(jié)果進(jìn)行分組排序,然后返回每組中的第一條數(shù)據(jù)。且是根據(jù)group by的后接字段進(jìn)行去重的。

例如:

mysql>selectsex,agefromstudentgroupbysex;
+--------+-----+
|sex|age|
+--------+-----+
|male|10|
|female|12|
+--------+-----+
2rowsinset(0.03sec)

distinct和group by原理

在大多數(shù)例子中,DISTINCT可以被看作是特殊的GROUP BY,它們的實現(xiàn)都基于分組操作,且都可以通過松散索引掃描、緊湊索引掃描(關(guān)于索引掃描的內(nèi)容會在其他文章中詳細(xì)介紹,就不在此細(xì)致介紹了)來實現(xiàn)。

DISTINCT和GROUP BY都是可以使用索引進(jìn)行掃描搜索的。例如以下兩條sql(只單單看表格最后extra的內(nèi)容),我們對這兩條sql進(jìn)行分析,可以看到,在extra中,這兩條sql都使用了緊湊索引掃描Using index for group-by。

所以,在一般情況下,對于相同語義的DISTINCT和GROUP BY語句,我們可以對其使用相同的索引優(yōu)化手段來進(jìn)行優(yōu)化。

mysql>explainselectint1_indexfromtest_distinct_groupbygroupbyint1_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|Usingindexforgroup-by|
+----+-------------+-----------------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
1rowinset(0.05sec)

mysql>explainselectdistinctint1_indexfromtest_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|Usingindexforgroup-by|
+----+-------------+-----------------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
1rowinset(0.05sec)

但對于GROUP BY來說,在MYSQL8.0之前,GROUP Y默認(rèn)會依據(jù)字段進(jìn)行隱式排序。

可以看到,下面這條sql語句在使用了臨時表的同時,還進(jìn)行了filesort。

mysql>explainselectint6_bigger_randomfromtest_distinct_groupbyGROUPBYint6_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|Usingtemporary;Usingfilesort|
+----+-------------+-----------------------+------------+------+---------------+------+---------+------+-------+----------+---------------------------------+
1rowinset(0.04sec)

隱式排序

對于隱式排序,我們可以參考Mysql官方的解釋

大致解釋一下:

GROUP BY 默認(rèn)隱式排序(指在 GROUP BY 列沒有 ASC 或 DESC 指示符的情況下也會進(jìn)行排序)。然而,GROUP BY進(jìn)行顯式或隱式排序已經(jīng)過時(deprecated)了,要生成給定的排序順序,請?zhí)峁?ORDER BY 子句。

所以,在Mysql8.0之前,Group by會默認(rèn)根據(jù)作用字段(Group by的后接字段)對結(jié)果進(jìn)行排序。在能利用索引的情況下,Group by不需要額外進(jìn)行排序操作;但當(dāng)無法利用索引排序時,Mysql優(yōu)化器就不得不選擇通過使用臨時表然后再排序的方式來實現(xiàn)GROUP BY了。

且當(dāng)結(jié)果集的大小超出系統(tǒng)設(shè)置臨時表大小時,Mysql會將臨時表數(shù)據(jù)copy到磁盤上面再進(jìn)行操作,語句的執(zhí)行效率會變得極低。這也是Mysql選擇將此操作(隱式排序)棄用的原因。

基于上述原因,Mysql在8.0時,對此進(jìn)行了優(yōu)化更新:

大致解釋一下:

從前(Mysql5.7版本之前),Group by會根據(jù)確定的條件進(jìn)行隱式排序。在mysql 8.0中,已經(jīng)移除了這個功能,所以不再需要通過添加order by null 來禁止隱式排序了,但是,查詢結(jié)果可能與以前的 MySQL 版本不同。要生成給定順序的結(jié)果,請按通過ORDER BY指定需要進(jìn)行排序的字段。

因此,我們的結(jié)論也出來了:

在語義相同,有索引的情況下:

group by和distinct都能使用索引,效率相同。因為group by和distinct近乎等價,distinct可以被看做是特殊的group by。

在語義相同,無索引的情況下:

distinct效率高于group by。原因是distinct 和 group by都會進(jìn)行分組操作,但group by在Mysql8.0之前會進(jìn)行隱式排序,導(dǎo)致觸發(fā)filesort,sql執(zhí)行效率低下。

但從Mysql8.0開始,Mysql就刪除了隱式排序,所以,此時在語義相同,無索引的情況下,group by和distinct的執(zhí)行效率也是近乎等價的。

推薦group by的原因

group by語義更為清晰

group by可對數(shù)據(jù)進(jìn)行更為復(fù)雜的一些處理

相比于distinct來說,group by的語義明確。且由于distinct關(guān)鍵字會對所有字段生效,在進(jìn)行復(fù)合業(yè)務(wù)處理時,group by的使用靈活性更高,group by能根據(jù)分組情況,對數(shù)據(jù)進(jìn)行更為復(fù)雜的處理,例如通過having對數(shù)據(jù)進(jìn)行過濾,或通過聚合函數(shù)對數(shù)據(jù)進(jìn)行運算。






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    906

    瀏覽量

    29534
  • null
    +關(guān)注

    關(guān)注

    0

    文章

    19

    瀏覽量

    4308

原文標(biāo)題:面試官:MySQL中的 distinct 和 group by 哪個效率更高?

文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    LTC7841:高性能雙相同步升壓控制器解析

    LTC7841:高性能雙相同步升壓控制器解析 電子設(shè)計領(lǐng)域,電源管理一直是至關(guān)重要的一環(huán)。對于需要高功率升壓的應(yīng)用,一款高效、穩(wěn)定且功能豐富的升壓控制器無疑是工程師們的理想之選。今天,我們就來
    的頭像 發(fā)表于 03-05 09:15 ?314次閱讀

    LT8550:多相同步降壓DC/DC轉(zhuǎn)換器擴展器的卓越之選

    LT8550:多相同步降壓DC/DC轉(zhuǎn)換器擴展器的卓越之選 電子設(shè)計領(lǐng)域,對于高電流、高效率電源系統(tǒng)的需求不斷增長。ADI公司的LT8550多相同步降壓DC/DC轉(zhuǎn)換器擴展器,憑借其
    的頭像 發(fā)表于 03-04 16:50 ?285次閱讀

    探秘MAX25203D/MAX25203E:雙相同步升壓控制器的卓越性能

    探秘MAX25203D/MAX25203E:雙相同步升壓控制器的卓越性能 汽車電子的復(fù)雜世界中,電子工程師們一直致力于尋找高性能、高可靠性的電源管理解決方案。今天,我們就來深入探討Analog
    的頭像 發(fā)表于 03-02 16:20 ?61次閱讀

    MAX8791單相同步 MOSFET 驅(qū)動器:設(shè)計與應(yīng)用詳解

    MAX8791/MAX8791B 單相同步 MOSFET 驅(qū)動器:設(shè)計與應(yīng)用詳解 引言 現(xiàn)代電子設(shè)備中,高效的電源管理至關(guān)重要。對于筆記本電腦、臺式機和服務(wù)器等設(shè)備的 CPU 核心電源供應(yīng),單相同
    的頭像 發(fā)表于 02-04 15:20 ?144次閱讀

    電源的效率如何觀察?

    %,所以這個標(biāo)準(zhǔn)反映了電源典型使用情況下效率。 100% 負(fù)載:這個標(biāo)準(zhǔn)表示電源的效率負(fù)載為100%時的性能。
    發(fā)表于 12-30 08:19

    如何高效修改西門子PLC的相同IP地址

    IP 地址重復(fù)沖突的問題,無法實現(xiàn)數(shù)據(jù)采集與遠(yuǎn)程通信,將直接影響到設(shè)備聯(lián)網(wǎng)率與信息化管理水平。 某企業(yè)多臺PLC控制的設(shè)備在上網(wǎng)時出現(xiàn)相同IP沖突問題。由于設(shè)備較多,如果要求廠商工程師來到現(xiàn)場逐一修改IP的方式效率較低。一方面采取
    的頭像 發(fā)表于 12-16 13:52 ?435次閱讀
    如何高效修改西門子PLC的<b class='flag-5'>相同</b>IP地址

    為什么sconscript這么寫,沒有構(gòu)建文件的情況下,反而會構(gòu)建所有文件?

    在有一個文件夾有返回的時候,構(gòu)建關(guān)系正常。 沒有任何選擇的情況下,構(gòu)建關(guān)系異常。(這時候應(yīng)該所有文件劃傷×且不編譯) 這是我sconscript的寫法
    發(fā)表于 09-24 07:41

    CNC的IP地址相同沖突如何解決?

    在網(wǎng)絡(luò)世界中,每個設(shè)備都需要一個獨特的標(biāo)識來確保信息的準(zhǔn)確傳輸,這個標(biāo)識就是IP地址。然而,CNC(數(shù)控機床)生產(chǎn)車間中,由于存在多個品牌、不同型號的設(shè)備,且這些設(shè)備在出廠測試時往往會被配備相同
    的頭像 發(fā)表于 07-23 14:13 ?692次閱讀
    CNC的IP地址<b class='flag-5'>相同</b>沖突如何解決?

    請問CYW20835sleep mode的情況下,不進(jìn)入SDS或HIDOF的情況下,底電流最低是多少?

    請問CYW20835sleep mode的情況下,不進(jìn)入SDS或HIDOF的情況下,底電流最低是多少?
    發(fā)表于 07-07 07:54

    十二相同步發(fā)電機降階等效模型研究

    摘要:十二相同步發(fā)電機整流系統(tǒng)能夠提供高品質(zhì)直流電能,但是發(fā)電機模型復(fù)雜,解析分析困難。為此,推導(dǎo)了十二相整流發(fā)電機的等效三相降階模型和狀態(tài)空間平均模型,簡化了模型復(fù)雜程度,提高了仿真計算效率。等效
    發(fā)表于 06-17 08:59

    國外PLC出現(xiàn)IP相同沖突如何解決

    設(shè)備是近期從不同供應(yīng)商采購而來,部分設(shè)備在出廠時被預(yù)設(shè)了相同的默認(rèn)IP地址,均為192.168.1.100。當(dāng)這些PLC同時接入工廠網(wǎng)絡(luò)時,網(wǎng)絡(luò)系統(tǒng)立即報錯,導(dǎo)致設(shè)備無法正常通信,整個監(jiān)控系統(tǒng)陷入癱瘓狀態(tài),生產(chǎn)線也被迫暫停。 面對這一緊急情況
    的頭像 發(fā)表于 05-15 17:05 ?874次閱讀
    國外PLC出現(xiàn)IP<b class='flag-5'>相同</b>沖突如何解決

    變頻器相同的故障原因不同的故障代碼分類

    變頻器相同的故障原因可能對應(yīng)不同的故障代碼,這主要取決于變頻器的型號、制造商以及具體的故障檢測機制。以下是一些常見的故障原因及其可能對應(yīng)的不同故障代碼分類: 一、過電流故障 ● 故障原因:電動機銘牌
    的頭像 發(fā)表于 04-25 14:31 ?2565次閱讀
    變頻器<b class='flag-5'>相同</b>的故障原因不同的故障代碼分類

    使用AD9122四倍插值的情況下,輸出20MHz的寬帶信號偶爾會出現(xiàn)頻譜混疊,怎么解決?

    你好,使用AD9122四倍插值的情況下,輸出20MHz的寬帶信號偶爾會出現(xiàn)頻譜混疊,這種該怎么解決
    發(fā)表于 04-15 06:50

    PCB仿真相同損耗,28G NRZ的產(chǎn)品不能直接升級到56G PAM4?

    內(nèi)能傳輸4位比特。說的有點干哈,那我們就大概畫個草圖,你們就能理解了。 所以基頻,也就是時鐘頻率不提升的情況下, PAM4就天然比NRZ多采樣一倍的比特,因此56G PAM4并不需要提升一倍的基頻
    發(fā)表于 03-11 11:32

    無感直流BLDC,大占空比情況下失步怎么解決?

    無感直流BLDC,大占空比情況下失步問題
    發(fā)表于 03-11 08:00