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

MySQL order by與group by查詢優(yōu)化實現(xiàn)詳解

 更新時間:2022年11月01日 11:20:08   作者:流煙默  
order by 子句盡量使用index方式排序(即using index),避免使用filesort方式排序(即using filesort)。Index方式效率高,它指MySQL掃描索引本身完成排序,filesort則效率低

前言

order by滿足兩種情況,會使用 index 方式排序:

  • order by語句使用索引最左前列(最左匹配法則)
  • where子句和order by子句條件列組合滿足最左匹配法則(where條件使用索引的最左前綴為常量)

下面給出幾個實例來說明,如下所示我們創(chuàng)建表并為其創(chuàng)建組合索引(c1,c2,c3)。

CREATE TABLE `testc` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `c1` varchar(100) DEFAULT NULL,
  `c2` varchar(100) DEFAULT NULL,
  `c3` varchar(100) DEFAULT NULL,
  `c4` varchar(100) DEFAULT NULL,
  `c5` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `testc_c1_IDX` (`c1`,`c2`,`c3`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

where與order by滿足最左匹配法則

# c1 c2滿足最左匹配法則
explain select * from testc where c1='a1' order by c2
# 與上面等價
explain select * from testc where c1='a1' order by c2,c3

key_len標(biāo)明查找用到了索引 c1,Extra中是Using index condition 沒有同時出現(xiàn)using where ,表明 c2 索引用來讀取數(shù)據(jù)而非執(zhí)行查找動作。

MySQL Innodb下的B+樹本身就是多路平衡樹,那么索引換句話就是排好序的快速查找數(shù)據(jù)結(jié)構(gòu)。如果order by用到了索引且排序和索引次序一樣,那么無疑效果是最好的。

中間斷裂

如下所示,缺少了c2,order by不滿足最左匹配法則。

explain select * from testc where c1='a1' order by c3

可以看到Extra中Using index condition; Using filesort說明雖然where可以用到索引(單獨c1滿足最左匹配),但是排序不滿足,故而出現(xiàn)了filesort。

大哥不在

如下c1不在,那么很顯然無論查找還是排序都用不到索引。

explain select * from testc where c2='a2' order by c3

這里Extra是Using where; Using filesort,說明通過where子句過濾結(jié)果,然后對結(jié)果進(jìn)行文件排序。

范圍失效

如下所示,中間c2是個范圍搜索,那么其后索引將失效也就是order by c3無法與where連接滿足最左匹配法則。

explain select * from testc where c1='a1' and c2 > 'a2' order by c3

如下圖所示,這里type = range,ken_len表示用到了 c1,c2索引。Extra是Using index condition; Using filesort表示查詢用到了索引但是無法利用索引完成的排序操作。

這種情況如何優(yōu)化呢?order by c2,c3!這樣就可以保證索引排序而不需要filesort。

explain select * from agriculture.testc where c1='a1' and c2  > 'a2' 
order by  c2,c3

order by 次序相反

如下所示,order by的次序沒有與索引次序保持一致。這里Extra為Using index condition; Using filesort。

explain select * from testc where c1='a1' order by c3,c2

覆蓋索引

前面幾個都是select *,這里查找索引列。

沒有where,order by滿足全值匹配,select查詢的數(shù)據(jù)是索引列。

explain select c1 from testc order by c1, c2,c3

這里Extra中只有Using index;

沒有where,order by 大哥丟失,select查詢的數(shù)據(jù)是索引列。

explain select c1 from testc order by c2,c3

這里Extra中是Using index; Using filesort 。

這里Extra信息為Using where; Using index; Using filesort。

explain select c1 from testc where c1='a1' order by c3,c2

filesort的兩種算法

filesort有兩種機(jī)制:雙路排序和單路排序。雙路排序簡單來講就是兩次掃描磁盤,最終得到數(shù)據(jù)。單路排序則是只需要讀取一次,也就是一次磁盤IO。

雙路排序

MySQL4.1之前是使用雙路排序,讀取行指針和order by列,對他們進(jìn)行排序,然后掃描已經(jīng)排序好的列表,按照列表中的值重新從列表中讀取對應(yīng)的數(shù)據(jù)輸出(可以理解為從磁盤讀取排序字段,在buffer進(jìn)行排序,然后再從磁盤讀取其他字段)。

取一批數(shù)據(jù)要進(jìn)行兩次磁盤IO,這是很耗時的。故而在MySQL4.1之后,出現(xiàn)了第二種改進(jìn)的算法,也就是單路排序。

單路排序

從磁盤讀取查詢需要的所有列,按照order by列在buffer對它們進(jìn)行排序,然后掃描排序后的列表進(jìn)行輸出。它的效率更快一點,避免了第二次讀取數(shù)據(jù),并且把隨機(jī)IO變成了順序IO。但是其會使用更多的空間,因為其緩存了數(shù)據(jù)在內(nèi)存中。

單路的問題

可能取出的數(shù)據(jù)大小超過了sort_buffer的容量,導(dǎo)致每次只能取sort_buffer容量大小的數(shù)據(jù)進(jìn)行排序(創(chuàng)建tmp文件,多路合并),排完再取sort_buffer容量大小…從而多次IO(可能比雙路更多)。

可以嘗試增大sort_buffer_size參數(shù)的設(shè)置或者max_length_for_sort_data參數(shù)的設(shè)置。

總結(jié)

order by時select * 是一個大忌,應(yīng)該是查詢需要的字段。

當(dāng)query的字段大小總和小于max_length_for_sort_data而且排序字段不是text|blob類型時,會用改進(jìn)后的算法–單路排序,否則使用雙路排序。

兩種算法的數(shù)據(jù)都有可能超出sort_buffer的容量,超出之后會創(chuàng)建tmp文件進(jìn)行合并排序?qū)е露啻蜪O。尤其對于單路排序來說風(fēng)險更大,所以需要適當(dāng)調(diào)整sort_buffer的容量。

提高max_length_for_sort_data會增加使用單路排序算法的概率。但是如果設(shè)置的太高,數(shù)據(jù)總?cè)萘砍^sort_buffer的概率就增大,明顯癥狀是磁盤IO高,CPU使用率低。

group by

前面提到的規(guī)則針對group by均適用,group by 實質(zhì)是先排序后分組,遵照索引建的最佳左前綴。當(dāng)無法使用索引時,增大max_length_for_sort_data和sort_buffer參數(shù)的值。

需要注意的是where優(yōu)先級高于having,能寫在where限定的條件盡量不要通過having。

到此這篇關(guān)于MySQL order by與group by查詢優(yōu)化實現(xiàn)詳解的文章就介紹到這了,更多相關(guān)MySQL order by與group by內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySql利用父id遞歸向下查詢子節(jié)點的方法實例

    MySql利用父id遞歸向下查詢子節(jié)點的方法實例

    項目中遇到一個需求,要求查處菜單節(jié)點的所有節(jié)點,在網(wǎng)上查了一下,大多數(shù)的方法用到了存儲過程,由于線上環(huán)境不能隨便添加存儲過程,所以自己寫一個,這篇文章主要給大家介紹了關(guān)于MySql利用父id遞歸向下查詢子節(jié)點的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • mysql隨機(jī)查詢10條數(shù)據(jù)的三種方法

    mysql隨機(jī)查詢10條數(shù)據(jù)的三種方法

    本文主要介紹了mysql隨機(jī)查詢10條數(shù)據(jù)的三種方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-09-09
  • MySQL的WHERE語句中BETWEEN與IN的使用教程

    MySQL的WHERE語句中BETWEEN與IN的使用教程

    這篇文章主要介紹了MySQL的WHERE語句中BETWEEN與IN的使用教程,是MySQL入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-12-12
  • MySQL深度分頁(千萬級數(shù)據(jù)量如何快速分頁)

    MySQL深度分頁(千萬級數(shù)據(jù)量如何快速分頁)

    后端開發(fā)中經(jīng)常需要分頁展示,個時候就需要用到MySQL的LIMIT關(guān)鍵字。LIMIT在數(shù)據(jù)量大的時候極可能造成的一個問題就是深度分頁。本文就介紹一下解決方法,感興趣的可以了解一下
    2021-07-07
  • MySQL對字符串使用STR_TO_DATE()函數(shù)詳解

    MySQL對字符串使用STR_TO_DATE()函數(shù)詳解

    文章介紹了MySQL中的STR_TO_DATE()函數(shù),用于將字符串轉(zhuǎn)換為日期時間類型,轉(zhuǎn)換時需要注意字符串格式、日期有效性等問題
    2025-03-03
  • MySQL 使用自定義變量進(jìn)行查詢優(yōu)化

    MySQL 使用自定義變量進(jìn)行查詢優(yōu)化

    MySQL自定義變量估計很少人有用到,但是如果用好了也是可以輔助進(jìn)行性能優(yōu)化的。需要注意的是變量是基于連接會話的,而且可能存在一些意外的情況,需要小心使用。本篇介紹如何利用自定義變量進(jìn)行查詢優(yōu)化,提高效率
    2021-05-05
  • 實例操作MySQL短鏈接

    實例操作MySQL短鏈接

    在本文里我們給大家總結(jié)了關(guān)于MySQL短鏈接的實操方法和相關(guān)知識點,有需要的朋友們跟著學(xué)習(xí)下。
    2019-03-03
  • MySQL中的SHOW FULL PROCESSLIST命令實現(xiàn)

    MySQL中的SHOW FULL PROCESSLIST命令實現(xiàn)

    SHOW FULL PROCESSLIST命令是MySQL中一個非常有用的工具,可以幫助我們理解和監(jiān)控MySQL服務(wù)器的狀態(tài),本文主要介紹了MySQL中的SHOW FULL PROCESSLIST命令,感興趣的可以了解一下
    2023-11-11
  • 論一條select語句在MySQL是怎樣執(zhí)行的

    論一條select語句在MySQL是怎樣執(zhí)行的

    本文將建立一套建立一套MySQL的知識框架,通過討論select語句在MySQL是怎樣執(zhí)行的來展開內(nèi)容,感興趣的小伙伴一起來看下文吧
    2021-08-08
  • Mysql中文亂碼以及導(dǎo)出為sql語句和Excel問題解決方法[圖文]

    Mysql中文亂碼以及導(dǎo)出為sql語句和Excel問題解決方法[圖文]

    這幾天基于Heritrix寫了一個爬蟲,用到mysql,在導(dǎo)入導(dǎo)出數(shù)據(jù)時,遇到一些亂碼問題,好不容易解決了,記錄一下,以備查看
    2013-04-04

最新評論

图木舒克市| 南靖县| 集安市| 绵竹市| 黑水县| 台安县| 桓仁| 常宁市| 岳西县| 兴化市| 梁河县| 电白县| 曲水县| 龙山县| 汉源县| 皮山县| 万安县| 阿合奇县| 上虞市| 津市市| 晴隆县| 天峨县| 周至县| 苍梧县| 汶川县| 祁门县| 建水县| 衡阳市| 交口县| 剑川县| 五大连池市| 亳州市| 铁力市| 九寨沟县| 同江市| 长武县| 东至县| 佛山市| 乌兰浩特市| 汝州市| 嘉义县|