最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL Group by的優(yōu)化詳解

 更新時(shí)間:2021年03月09日 11:11:57   作者:萌新J  
這篇文章主要介紹了MySQL Group by 優(yōu)化的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用MySQL,感興趣的朋友可以了解下

一個(gè)標(biāo)準(zhǔn)的 Group by 語(yǔ)句包含排序、分組、聚合函數(shù),比如 select a,count(*) from t group by a ;  這個(gè)語(yǔ)句默認(rèn)使用 a 進(jìn)行排序。如果 a 列沒(méi)有索引,那么就會(huì)創(chuàng)建臨時(shí)表來(lái)統(tǒng)計(jì) a和 count(*),然后再通過(guò) sort_buffer 按 a 進(jìn)行排序。

標(biāo)準(zhǔn)的執(zhí)行流程

結(jié)構(gòu):

create table t1(id int primary key, a int, b int, index(a));
delimiter ;;
create procedure idata()
begin
 declare i int;

 set i=1;
 while(i<=1000)do
 insert into t1 values(i, i, i);
 set i=i+1;
 end while;
end;;
delimiter ;
call idata();

函數(shù)就是向 t1 中插入1000條語(yǔ)句,從(1,1,1) 到(1000,1000,1000)。

執(zhí)行   select id%10 as m, count(*) as c from t1 group by m;

解析:

Using index,表示這個(gè)語(yǔ)句使用了覆蓋索引,選擇了索引 a,不需要回表;
Using temporary,表示使用了臨時(shí)表;
Using filesort,表示需要排序。

過(guò)程:

1、創(chuàng)建內(nèi)存臨時(shí)表,表里有兩個(gè)字段 m 和 c,主鍵是 m;
2、掃描表 t1 的索引 a,依次取出葉子節(jié)點(diǎn)上的 id 值,計(jì)算 id%10 的結(jié)果,記為 x;
  1)如果臨時(shí)表中沒(méi)有主鍵為 x 的行,就插入一個(gè)記錄 (x,1);
  2)如果表中有主鍵為 x 的行,就將 x 這一行的 c 值加 1;

第2 步如果發(fā)現(xiàn)內(nèi)存臨時(shí)表存儲(chǔ)的總字段長(zhǎng)度到達(dá)參數(shù) tmp_table_size 設(shè)置的大小,那么就會(huì)將內(nèi)存臨時(shí)表升級(jí)為磁盤(pán)臨時(shí)表,然后重新開(kāi)始遍歷計(jì)算。
3、遍歷完成后,再根據(jù)字段 m 做排序,得到結(jié)果集返回給客戶(hù)端。

最后的排序就是下圖虛線(xiàn)框中的操作,如果 sort_buffer 設(shè)置的大小不夠大,那么就會(huì)使用臨時(shí)表來(lái)輔助排序。

優(yōu)化

未優(yōu)化(也就是分組列沒(méi)有索引)的 group by 的總過(guò)程可以概括為:因?yàn)閿?shù)據(jù)是無(wú)序的,所以需要?jiǎng)?chuàng)建臨時(shí)表,然后一個(gè)一個(gè)判斷屬于哪個(gè)分組,最后再根據(jù)分組列進(jìn)行排序。所以,優(yōu)化可以有兩個(gè)思路:

去掉排序

在明確返回的數(shù)據(jù)不需要排序的情況下,可以禁止排序,也就是將上面的語(yǔ)句改成 select a,count(*) from t group by a order by null。

順序排列

如果記錄都按照排序字段排序,那么數(shù)據(jù)就變成了下面的結(jié)構(gòu):

這樣在實(shí)際獲取要返回的字段或計(jì)算聚合函數(shù)時(shí),只需要按順序依次訪問(wèn),等到列值變成下一個(gè)就知道當(dāng)前組訪問(wèn)結(jié)束,將之前統(tǒng)計(jì)的數(shù)據(jù)直接返回。這樣就避免了創(chuàng)建臨時(shí)表,同時(shí)排序也不需要使用 sort_buffer 進(jìn)行額外排序。這樣就極大地提高了執(zhí)行的效率。

實(shí)現(xiàn)

1、如果分組字段適合創(chuàng)建索引就直接為分組字段創(chuàng)建索引。

MySQL 5.7 版本支持了 generated column 機(jī)制,用來(lái)實(shí)現(xiàn)列數(shù)據(jù)的關(guān)聯(lián)更新。你可以用下面的方法創(chuàng)建一個(gè)列 z,然后在 z 列上創(chuàng)建一個(gè)索引(如果是 MySQL 5.6 及之前的版本,你也可以創(chuàng)建普通列和索引,來(lái)解決這個(gè)問(wèn)題)

alter table t1 add column z int generated always as(id % 100), add index(z);

然后解析:

這時(shí)沒(méi)有用到臨時(shí)表和額外排序,所以性能提升。

2、如果分組字段不適合(使用率很低),那么可以使用 SQL_BIG_RESULT 來(lái)嘗試優(yōu)化。

在 group by 語(yǔ)句中加入 SQL_BIG_RESULT 這個(gè)提示(hint),就可以告訴優(yōu)化器:這個(gè)語(yǔ)句涉及的數(shù)據(jù)量很大,請(qǐng)直接用磁盤(pán)臨時(shí)表。MySQL 的優(yōu)化器一看,磁盤(pán)臨時(shí)表是 B+ 樹(shù)存儲(chǔ),存儲(chǔ)效率不如數(shù)組來(lái)得高。所以,既然使用SQL_BIG_RESULT來(lái)說(shuō)明數(shù)據(jù)量很大,那從磁盤(pán)空間考慮,還是直接用數(shù)組來(lái)存吧。所以在使用 SQL_BIG_RESULT 后優(yōu)化器會(huì)使用數(shù)組結(jié)構(gòu)的磁盤(pán)臨時(shí)表。

但是如果在未達(dá)到磁盤(pán)臨時(shí)表的使用條件是不會(huì)使用磁盤(pán)臨時(shí)表的,也就是在 sort_buffer 空間能夠存儲(chǔ)要返回和排序的總字段長(zhǎng)度時(shí),就使用數(shù)組結(jié)構(gòu)的 sort_buffer ,如果總字段超過(guò) sort_buffer 大小,那么就再加上數(shù)組結(jié)構(gòu)的磁盤(pán)臨時(shí)表來(lái)幫助排序。

那么在 sort_buffer 空間足夠的情況下, sort_buffer 內(nèi)部就會(huì)對(duì)數(shù)據(jù)進(jìn)行排序,這樣也就起到了索引的作用,

還是以上面的例子來(lái)看,使用 SQL_BIG_RESULT

alter table t1 add column z int generated always as(id % 100), add index(z);

具體過(guò)程如下:

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

解析:

可以看到此時(shí)就沒(méi)有使用臨時(shí)表了,而是直接使用 sort_buffer 進(jìn)行排序,這樣就省去了使用臨時(shí)表帶來(lái)的性能消耗。

總結(jié)

1、如果對(duì) group by 語(yǔ)句的結(jié)果沒(méi)有排序要求,要在語(yǔ)句后面加 order by null;那么一般情況就不需要使用臨時(shí)表了(上面兩個(gè)優(yōu)化都是在要求排序的前提下提出的優(yōu)化方式)
2、盡量讓 group by 過(guò)程用上表的索引,確認(rèn)方法是 explain 結(jié)果里沒(méi)有 Using temporary 和 Using filesort;
3、如果 group by 需要統(tǒng)計(jì)的數(shù)據(jù)量不大,盡量只使用內(nèi)存臨時(shí)表;也可以通過(guò)適當(dāng)調(diào)大 tmp_table_size 參數(shù),來(lái)避免用到磁盤(pán)臨時(shí)表;
4、如果數(shù)據(jù)量實(shí)在太大,使用 SQL_BIG_RESULT 這個(gè)提示,來(lái)告訴優(yōu)化器直接使用排序算法得到 group by 的結(jié)果。

以上就是詳解MySQL Group by 優(yōu)化的詳細(xì)內(nèi)容,更多關(guān)于MySQL Group by 優(yōu)化的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • MySQL max_allowed_packet的坑

    MySQL max_allowed_packet的坑

    max_allowed_packet是 MySQL 中的一個(gè)設(shè)定參數(shù),用于設(shè)定所接受的包的大小,根據(jù)情形不同,其缺省值可能是 1M 或者 4M,本文主要介紹了MySQL max_allowed_packet的坑,感興趣的可以了解一下
    2024-01-01
  • MySQL數(shù)據(jù)庫(kù)事務(wù)隔離級(jí)別詳解

    MySQL數(shù)據(jù)庫(kù)事務(wù)隔離級(jí)別詳解

    這篇文章主要介紹了MySQL數(shù)據(jù)庫(kù)事務(wù)隔離級(jí)別詳解的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • 一文帶你了解MySQL的左連接與右連接

    一文帶你了解MySQL的左連接與右連接

    在MySQL中,左查詢(xún)和右查詢(xún)是通過(guò)使用LEFT?JOIN和RIGHT?JOIN關(guān)鍵字來(lái)執(zhí)行的,本文通過(guò)詳細(xì)的代碼示例簡(jiǎn)單介紹這兩種查詢(xún)方法的語(yǔ)法,需要的朋友可以參考下
    2023-07-07
  • mysql心得分享:存儲(chǔ)過(guò)程

    mysql心得分享:存儲(chǔ)過(guò)程

    MySQL 5.0以后的版本開(kāi)始支持存儲(chǔ)過(guò)程,存儲(chǔ)過(guò)程具有一致性、高效性、安全性和體系結(jié)構(gòu)等特點(diǎn),本文主要來(lái)分享下本人關(guān)于存儲(chǔ)過(guò)程的一些心得體會(huì)。
    2014-07-07
  • Mysql遷移Postgresql的實(shí)現(xiàn)示例

    Mysql遷移Postgresql的實(shí)現(xiàn)示例

    本文主要介紹了Mysql遷移Postgresql的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • mysql修改密碼的三方法和忘記root密碼的解決方法

    mysql修改密碼的三方法和忘記root密碼的解決方法

    這篇文章主要介紹了mysql修改密碼的三方法和忘記root密碼的解決方法,需要的朋友可以參考下
    2014-02-02
  • mysql 5.7.11 winx64安裝配置方法圖文教程

    mysql 5.7.11 winx64安裝配置方法圖文教程

    這篇文章主要為大家分享了mysql 5.7.11winx64安裝配置方法圖文教程,感興趣的朋友可以參考一下
    2016-07-07
  • mysql中取系統(tǒng)當(dāng)前時(shí)間,當(dāng)前日期方便查詢(xún)判定的代碼

    mysql中取系統(tǒng)當(dāng)前時(shí)間,當(dāng)前日期方便查詢(xún)判定的代碼

    今天在寫(xiě)一段查詢(xún)語(yǔ)句的時(shí)候,需要判定結(jié)束日期是不是大于當(dāng)前日期,一般情況下都是通過(guò)php判定日期,然后查詢(xún)。
    2011-12-12
  • mysql 的replace into實(shí)例詳解

    mysql 的replace into實(shí)例詳解

    這篇文章主要介紹了mysql 的replace into實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • 深入淺析MySQL COLUMNS分區(qū)

    深入淺析MySQL COLUMNS分區(qū)

    COLUMN分區(qū)是5.5開(kāi)始引入的分區(qū)功能,只有RANGE COLUMN和LIST COLUMN這兩種分區(qū);支持整形、日期、字符串;RANGE和LIST的分區(qū)方式非常的相似。下面就兩者的區(qū)別給大家介紹下,對(duì)mysql columns知識(shí)感興趣的朋友一起看看吧
    2016-11-11

最新評(píng)論

吉首市| 丹寨县| 卓资县| 唐海县| 资中县| 萨迦县| 平凉市| 蓬安县| 清丰县| 星子县| 绥宁县| 克东县| 金门县| 河东区| 高阳县| 临漳县| 兰溪市| 渑池县| 博客| 三原县| 来安县| 昌邑市| 黄冈市| 凤冈县| 五大连池市| 小金县| 沛县| 丽水市| 镇安县| 华蓥市| 巴楚县| 启东市| 拉孜县| 永靖县| 永寿县| 永泰县| 东明县| 安国市| 安新县| 浠水县| 行唐县|