国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

一篇文章了解MySQL的group by

這篇具有很好參考價(jià)值的文章主要介紹了一篇文章了解MySQL的group by。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

準(zhǔn)備工作!

1.本文章MySQL使用的是5.7,引擎使用的是innodb
2. 使用的表結(jié)構(gòu)(t1),字段a上有一個(gè)索引,
一篇文章了解MySQL的group by

1. group by常用方法:

group by的常規(guī)用法是配合聚合函數(shù),利用分組信息進(jìn)行統(tǒng)計(jì),常見的是配合max等聚合函數(shù)篩選數(shù)據(jù)后分析,以及配合having進(jìn)行篩選后過濾。
聚合函數(shù)

  • count(),返回指定列中數(shù)據(jù)的個(gè)數(shù)
  • sum(),返回指定列中數(shù)據(jù)的總和
  • avg(),返回指定列中數(shù)據(jù)的平均值
  • min(),返回指定列中數(shù)據(jù)的最小值
  • max(),返回指定列中數(shù)據(jù)的最大值

示例1: 查詢t1表,按照字段b進(jìn)行分組,并求出分組后b字段a的總和。

SELECT  MAX(a) from t1 GROUP BY b

實(shí)例2:查詢t1表,按照字段b進(jìn)行分組,拿到b<100的所有數(shù)據(jù),求出a的總和。

SELECT  MAX(a) from t1 GROUP BY b HAVING b<100

where和having區(qū)別

where子句將單個(gè)行過濾到查詢結(jié)果中,而having子句將分組過濾到查詢結(jié)果中 having子句中使用的列名必須出現(xiàn)在group by子句列表中,或包括在聚集函數(shù)中。

having子句的條件運(yùn)算至少包括一個(gè)聚集函數(shù),否則可以把查詢條件移到where字句中來過濾單個(gè)行(注意聚集函數(shù)不可以用在where子句中)


2. group by語(yǔ)句執(zhí)行流程:

我們執(zhí)行以下語(yǔ)句

SELECT  b, count(*) as c from t1 GROUP BY b HAVING b<100

查看explain執(zhí)行情況,由于b字段上沒有索引,所以進(jìn)行全表掃描。
一篇文章了解MySQL的group by

Using temporary; 表示使用了臨時(shí)表;
Using filesort ,表示需要排序。

由于字段b上沒有索引,它的執(zhí)行順序是這樣的

  • 創(chuàng)建內(nèi)存臨時(shí)表,表里有兩個(gè)字段 b 和 c,主鍵是 b;
  • 對(duì)t1表進(jìn)行全表掃描,并取出第一條數(shù)據(jù),判斷b是否小于100。如果b<100,就記錄b的值為X,并存入臨時(shí)表。
    1.如果臨時(shí)表中沒有主鍵為b的行,就插入一條記錄 b,c(x,1)
    2.如果臨時(shí)表中有主鍵為b的行,就更新主鍵為b的這一行,并把c的值進(jìn)行加1
  • 遍歷完成后,再根據(jù)字段 b做排序,得到結(jié)果集返回給客戶端。

在MySQL當(dāng)中排序有兩種
第一種是 全字段排序 ,第二種是 rowid 排序。 具體可以通過我的這篇文章去了解一篇文章搞懂MySQL的order by


3.使用group by會(huì)有哪些問題:

我們執(zhí)行以下語(yǔ)句

SELECT  b, count(*) as c from t1 GROUP BY b HAVING b<100

在上述中,由于b字段沒有索引,索引MySQL默認(rèn)會(huì)對(duì)此語(yǔ)句進(jìn)行排序。相信你也看了我的一篇文章搞懂MySQL的order by這篇文章,也了解了MySQL什么時(shí)候會(huì)用全字段排序,什么時(shí)候用 rowid 排序。

1. 使用磁盤臨時(shí)文件進(jìn)行排序

在此語(yǔ)句中,優(yōu)化器使用的是全字段排序,那么使用全字段排序會(huì)有哪些問題?
在全字段排序中,它是通過sort_buffer進(jìn)行排序,定義如下。

sort_buffer_size:就是 MySQL 為排序開辟的內(nèi)存(sort_buffer)的大小。如果要排序的數(shù)據(jù)量小于sort_buffer_size,排序就在內(nèi)存中完成。但如果排序數(shù)據(jù)量太大,內(nèi)存放不下,則不得不利用磁盤臨時(shí)文件輔助排序。

假如我們?nèi)缦耂QL語(yǔ)句查出有1億行,這時(shí)由于我們查詢數(shù)據(jù)大小超過了定義的 臨時(shí)排序文件( sort_buffer_size)的大小時(shí),

SELECT  b, count(*) as c from t1 GROUP BY b HAVING b<100000000

那么,這時(shí)就需要使用外部排序,外部排序一般使用歸并排序算法。可以這么簡(jiǎn)單理解,MySQL 將需要排序的數(shù)據(jù)分成 n份,每一份單獨(dú)排序后存在這些臨時(shí)文件中。然后把這n個(gè)有序文件再合并成一個(gè)有序的大文件。由于分成的的臨時(shí)文件很多,就會(huì)造成排序的性能很差。


2. 查詢數(shù)據(jù)超過臨時(shí)文件大小(tmp_table_size)

這個(gè)例子里由于臨時(shí)表只有 100 行,內(nèi)存可以放得下,因此全程只使用了內(nèi)存臨時(shí)表。但是,內(nèi)存臨時(shí)表的大小是有限制的,參數(shù) tmp_table_size 就是控制這個(gè)內(nèi)存大小的,默認(rèn)是 16M。接下來我把tmp_table_size大小改成1kb。

假如我們?nèi)缦耂QL語(yǔ)句查出有1億行,這時(shí)由于我們查詢數(shù)據(jù)大小超過了定義的 臨時(shí)文件( tmp_table_size)的大小時(shí)。

SELECT  b, count(*) as c from t1 GROUP BY b HAVING b<100000000

那么,這時(shí)就會(huì)把內(nèi)存臨時(shí)表轉(zhuǎn)成磁盤臨時(shí)表(磁盤臨時(shí)表默認(rèn)使用的引擎是 InnoDB)。由于我們數(shù)據(jù)量很大,很可能這個(gè)查詢需要的磁盤臨時(shí)表就會(huì)占用大量的磁盤空間。


4.group by的優(yōu)化方法:

我們還是以這條SQL語(yǔ)句為準(zhǔn)

SELECT  b, count(*) as c from t1 GROUP BY b HAVING b<100

1. 如果你的需求并不需要對(duì)結(jié)果進(jìn)行排序,那你可以在 SQL 語(yǔ)句末尾增加 order by null

explain SELECT  b, count(*) as c from t1 GROUP BY b HAVING b<100 ORDER BY null 

查看explain 結(jié)果一篇文章了解MySQL的group by

Using temporary; 表示使用了臨時(shí)表;


2. 可以對(duì)group by字段建立索引

眾所周知,由于我們MySQL的InnoDB引擎使用的數(shù)據(jù)結(jié)構(gòu)是B+樹,而B+樹相比于B樹最顯著的特征就是B+樹葉子節(jié)點(diǎn)是一個(gè)有序的雙向列表。既然他已經(jīng)有序了,那么我們是不是可以直接不進(jìn)行排序了。

我們執(zhí)行以下SQL語(yǔ)句,并在字段b上建立索引

SELECT  b, count(*) as c from t1 GROUP BY b HAVING b<100

查看explain執(zhí)行情況,沒有進(jìn)行排序,沒有使用臨時(shí)文件
一篇文章了解MySQL的group by

Using index;使用了覆蓋索引。
由于字段b上有索引,它的執(zhí)行順序是這樣的

一篇文章了解MySQL的group by

執(zhí)行流程:

  • 掃描t1表的索引b,讀取磁盤塊1,將磁盤塊加載到內(nèi)存中判斷50是否小于100,是就走左邊,不是就走右邊。

  • 掃描磁盤塊2,將磁盤塊加載到內(nèi)存中判斷判斷30是否小于100,是就走左邊,不是就走右邊。

  • 讀取磁盤塊3,將磁盤塊加載到內(nèi)存中判斷判斷20是否小100,是就走左邊,不是就走右邊。

  • 讀取磁盤塊4也就是葉子節(jié)點(diǎn),它是一個(gè)有序的鏈表。從鍵值10開始向后遍歷篩選所有符合篩選條件的數(shù)據(jù),并將符合篩選條件的data值數(shù)據(jù)緩存到結(jié)果集。(因?yàn)槭请p向有序的,所以會(huì)依次讀取,并不需要回到父節(jié)點(diǎn)。因此當(dāng)讀取到20后會(huì)直接讀取磁盤塊5)
    1.當(dāng)碰到第一個(gè) 10 的時(shí)候,結(jié)果集里的第一行就是 (10,1);
    2.當(dāng)碰到第二個(gè) 10 的時(shí)候,已經(jīng)知道累積了 1 個(gè) 10,修改結(jié)果集里的第一行為(10,2);

  • 當(dāng)依次讀取導(dǎo)磁盤塊12后,將磁盤塊加載到內(nèi)存中判斷100是否小于100,不是;就不需再向后查找,查詢終止。將結(jié)果集返回給用戶。

因此當(dāng)我們掃描到整個(gè)輸入的數(shù)據(jù)結(jié)束,就可以拿到 group by 的結(jié)果,不需要臨時(shí)表,也不需要再額外排序


3. group by字段無法建立索引時(shí)

如果可以通過加索引來完成 group by 邏輯就再好不過了。但是,如果碰上不適合創(chuàng)建索引的場(chǎng)景,我們還是要老老實(shí)實(shí)做排序的。那么,這時(shí)候的 group by 要怎么優(yōu)化呢?

如果我們明明知道,一個(gè) group by語(yǔ)句中需要放到臨時(shí)表上的數(shù)據(jù)量特別大,卻還是要按照“先放到內(nèi)存臨時(shí)表,插入一部分?jǐn)?shù)據(jù)后,發(fā)現(xiàn)內(nèi)存臨時(shí)表不夠用了再轉(zhuǎn)成磁盤臨時(shí)表”,這樣看上去就有點(diǎn)兒傻。

我們執(zhí)行以下SQL語(yǔ)句,并使用 SQL_BIG_RESULT(SQL_BIG_RESULT告訴mysql的分組語(yǔ)句必須使用磁盤臨時(shí)表)

SELECT  SQL_BIG_RESULT b, count(*) as c from t1 GROUP BY b HAVING b<100

查看explain執(zhí)行情況
一篇文章了解MySQL的group by
Using filesort 表示需要排序。

執(zhí)行流程:

  • .初始化 sort_buffer,確定放入一個(gè)整型字段,記為 b;
  • . 掃描表 t1 ,依次取出里面b<100的值, 將b的值存入 sort_buffer 中;
  • . 掃描完成后,對(duì) sort_buffer 的字段 b 做排序(如果 sort_buffer 內(nèi)存不夠用,就會(huì)利用磁盤臨時(shí)文件輔助排序);
  • . 排序完成后,就得到了一個(gè)有序數(shù)組。

在根據(jù)有序數(shù)組,得到數(shù)組里面的不同值,以及每個(gè)值的出現(xiàn)次數(shù)。


5. MySQL8.0之后版本的group by

我們還是以這條SQL語(yǔ)句為準(zhǔn)(MySQL版本8.0.26)

SELECT  b, count(*) as c from t1 GROUP BY b HAVING b<100

查看explain執(zhí)行情況
一篇文章了解MySQL的group by
Using temporary; 表示使用了臨時(shí)表;

group by 在 MySQL5.7 版本會(huì)自動(dòng)排序,但是在MySQL8 .0之后版本就去掉了自動(dòng)排序功能。


6.總結(jié)

1.如果對(duì) group by 語(yǔ)句的結(jié)果沒有排序要求,要在語(yǔ)句后面加 order by null;

2.盡量讓 group by 過程用上表的索引,確認(rèn)方法是 explain 結(jié)果里沒有 Using temporary 和 Using filesort;

3.如果 group by 需要統(tǒng)計(jì)的數(shù)據(jù)量不大,盡量只使用內(nèi)存臨時(shí)表;也可以通過適當(dāng)調(diào)大 tmp_table_size 參數(shù),來避免用到磁盤臨時(shí)表;

4.如果數(shù)據(jù)量實(shí)在太大,使用 SQL_BIG_RESULT 這個(gè)提示,來告訴優(yōu)化器直接使用排序算法得到 group by 的結(jié)果。

5.group by 在 MySQL5.7 版本會(huì)自動(dòng)排序,但是在MySQL8 .0之后版本就去掉了排序功能。


一篇文章了解MySQL的group by文章來源地址http://www.zghlxwxcb.cn/news/detail-451305.html

今晚我支持總監(jiān),法國(guó)沖沖沖?。。?/h3>

到了這里,關(guān)于一篇文章了解MySQL的group by的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 一篇文章帶你了解-selenium工作原理詳解

    一篇文章帶你了解-selenium工作原理詳解

    前言 Selenium是一個(gè)用于Web應(yīng)用程序自動(dòng)化測(cè)試工具。Selenium測(cè)試直接運(yùn)行在瀏覽器中,就像真正的用戶在操作一樣。支持的瀏覽器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。 主要功能包括:測(cè)試與瀏覽器的兼容性——測(cè)試你的應(yīng)用程序看是否能夠很好得

    2024年02月10日
    瀏覽(26)
  • 【C++】一篇文章帶你深入了解list

    【C++】一篇文章帶你深入了解list

    list是可以在常數(shù)范圍內(nèi)在任意位置進(jìn)行插入和刪除的序列式容器,并且該容器可以前后雙向迭代。 list的底層是雙向鏈表結(jié)構(gòu),雙向鏈表中每個(gè)元素存儲(chǔ)在互不相關(guān)的獨(dú)立節(jié)點(diǎn)中,在節(jié)點(diǎn)中通過指針指向其前一個(gè)元素和后一個(gè)元素。 list與forward_list非常相似:最主要的不同在

    2024年04月23日
    瀏覽(30)
  • 一篇文章帶你詳細(xì)了解axios的封裝

    一篇文章帶你詳細(xì)了解axios的封裝

    對(duì)請(qǐng)求的封裝在實(shí)際項(xiàng)目中是十分必要的,它可以讓我們統(tǒng)一處理 http 請(qǐng)求。比如做一些攔截,處理一些錯(cuò)誤等。本篇文章將詳細(xì)介紹如何封裝 axios 請(qǐng)求,具體實(shí)現(xiàn)的功能如下 基本配置 配置默認(rèn)請(qǐng)求地址,超時(shí)等 請(qǐng)求攔截 攔截 request 請(qǐng)求,處理一些發(fā)送請(qǐng)求之前做的處理,譬如給

    2024年02月07日
    瀏覽(30)
  • 【C++】一篇文章帶你深入了解string

    【C++】一篇文章帶你深入了解string

    C語(yǔ)言中,字符串是以’\\0’結(jié)尾的一些字符的集合,為了操作方便,C標(biāo)準(zhǔn)庫(kù)中提供了一些str系列的庫(kù)函數(shù),但是這些庫(kù)函數(shù)與字符串是分離開的,不太符合OOP的思想,而且底層空間需要用戶自己管理,稍不留神可能還會(huì)越界訪問。 string的文檔介紹 字符串是表示字符序列的類

    2024年04月08日
    瀏覽(26)
  • 【C++】一篇文章帶你深入了解vector

    【C++】一篇文章帶你深入了解vector

    vector的文檔介紹 vector是表示可變大小數(shù)組的序列容器。 就像數(shù)組一樣,vector也采用的連續(xù)存儲(chǔ)空間來存儲(chǔ)元素。也就是意味著可以采用下標(biāo)對(duì)vector的元素進(jìn)行訪問,和數(shù)組一樣高效。但是又不像數(shù)組,它的大小是可以動(dòng)態(tài)改變的,而且它的大小會(huì)被容器自動(dòng)處理。 本質(zhì)講,

    2024年04月22日
    瀏覽(36)
  • 這篇文章,讓你了解ERC-1155 多代幣標(biāo)準(zhǔn)協(xié)議

    用于多種代幣管理的合約標(biāo)準(zhǔn)接口。 單個(gè)部署的合約可以包括同質(zhì)化代幣、非同質(zhì)化代幣或其他配置(如半同質(zhì)化代幣)的任何組合。 ERC1155 的顯著特點(diǎn)是它使用單個(gè)智能合約一次代表多個(gè)代幣。這就是為什么它的balanceOf功能不同于 ERC20 和 ERC777 的原因:它有一個(gè)額外的id參

    2024年02月01日
    瀏覽(18)
  • 通過一篇文章讓你了解Linux的重要性

    通過一篇文章讓你了解Linux的重要性

    Linux是一種自由和開放源代碼的操作系統(tǒng),由林納斯·托瓦茲于1991年首次發(fā)布。它基于Unix,具有模塊化設(shè)計(jì),支持多任務(wù)和多用戶,能在多種硬件平臺(tái)上運(yùn)行。Linux系統(tǒng)在全球范圍內(nèi)得到廣泛應(yīng)用,包括服務(wù)器、移動(dòng)設(shè)備、嵌入式系統(tǒng)等領(lǐng)域。其強(qiáng)大的功能、穩(wěn)定性和安全性

    2024年04月15日
    瀏覽(24)
  • WAF是什么?一篇文章帶你全面了解WAF

    Web應(yīng)用程序防火墻(Web Application Firewall,WAF)是一種用于保護(hù)Web應(yīng)用程序的安全設(shè)備。Web應(yīng)用程序是指通過Web瀏覽器或其他Web客戶端訪問的應(yīng)用程序。WAF的目的是保護(hù)Web應(yīng)用程序免受黑客、網(wǎng)絡(luò)攻擊和數(shù)據(jù)泄漏等安全威脅的攻擊。 在這篇文章中,我們將深入探討WAF的工作原理

    2024年02月10日
    瀏覽(22)
  • 【網(wǎng)絡(luò)安全】一篇文章帶你了解CTF那些事兒

    【網(wǎng)絡(luò)安全】一篇文章帶你了解CTF那些事兒

    CTF(Capture The Flag)中文一般譯作奪旗賽,在網(wǎng)絡(luò)安全領(lǐng)域中指的是網(wǎng)絡(luò)安全技術(shù)人員之間進(jìn)行技術(shù)競(jìng)技的一種比賽形式。CTF起源于1996年DEFCON全球黑客大會(huì),以代替之前黑客們通過互相發(fā)起真實(shí)攻擊進(jìn)行技術(shù)比拼的方式。已經(jīng)成為全球范圍網(wǎng)絡(luò)安全圈流行的競(jìng)賽形式,2013年全

    2024年02月08日
    瀏覽(24)
  • 一篇文章讓你徹底了解vuex的使用及原理(上)

    文章講解的 Vuex 的版本為 4.1.0 ,會(huì)根據(jù)一些 api 來深入源碼講解,幫助大家更快掌握 vuex 的使用。 使用 Vue 實(shí)例的 use 方法把 Vuex 實(shí)例注入到 Vue 實(shí)例中。 use 方法執(zhí)行的是插件的中的 install 方法 src/store.js 從上面可以看到 Vue 實(shí)例通過 provide 方法把 store 實(shí)例 provide 到了根實(shí)例

    2023年04月23日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包