MySQL 16 order by如何運作

2021-10-11 09:21:20 字數 2424 閱讀 2828

order by:根據提供的字段進行排序;用法:order by column[asc(預設) | desc]。

limit:從結果集上再進行刷選;用法:limit offset ,rows。

如下語句建表:給city建索引

create table a(

id int(11) not null,

name varchar(16) not null,

age varchar(16) not null,

city varchar(16) not null,

primary key(id),

key city (city)

)engine = innodb

當我們查詢city = 「南京」時的sql語句。

select name,age,city from a where city="南京" order by age limit 10
我們用explain命令看下語句,發現它使用的是city索引,而且extra是using filesort,表示是需要排序的。

mysql會給每個執行緒分配一塊記憶體用於排序,叫做sort_buffer

16.1 全欄位排序

sql語句的執行流程:

初始化sort_buffer,確定name,age,city三個字段

去city索引中找到第乙個滿足city="南京"的資料,得到id

帶著上面的id去id主鍵索引樹中尋找對應的資料行,取出name,age,city字段值存入sort_buffer

從city索引去下乙個滿足條件的id

重複3,4步,直到從city索引中取不到滿足條件的id

對sort_buffer中的資料根據age進行排序

流程示意圖如下:

上面流程的第五步,根據age將資料進行排序,可能是在記憶體中進行,也可能借助了臨時檔案。這取決於引數sort_buffer_size的大小與所需要的記憶體大小。如果排序資料量過大,無法在記憶體中完成排序,就必需要借助於磁碟臨時檔案輔助排序。排序磁碟臨時檔案的演算法是歸併演算法,歸併演算法的思想是分而治之。

16.2 row id 排序

mysql中有個引數max_length_for_sort_data表示用於排序的當行長度,如果我們排序的字段有a,b,c…h這麼多,記憶體中存下資料有限,必定會借用更多的磁碟臨時表,效能不佳。

當出現單行的資料長度超過引數設定值,排序的列只會是 主鍵 id和 需要排序列。

sql語句的執行流程:

初始化sort_buffer,確定主鍵id,age列

從city索引中查詢到第乙個滿足city = 「南京」資料並取到id

帶著主鍵id去id索引樹找到對應的資料行,取出age,id兩列放入sort_buffer中

去city索引樹繼續找到下乙個滿足條件的資料,取出id

重複3,4步,直到city索引樹找不到滿足條件的資料。

對sort_buffer中的資料根據age進行排序

遍歷排序結果,根據id去id索引樹中取到name,age,city返回給客戶端

流程示意圖:

16.3討論及優化

使用臨時表排序會造成較大的效能消耗,能用記憶體盡量用記憶體,減少磁碟訪問。

利用索引覆蓋規則,我們建立name,age,city可以減少回表的步驟,直接得到結果。

利用磁碟檔案的目的是為了排序,那我們通過建立聯合索引,在當初資料放置的時候就已經排序好,我們取出來可以直接用。

像這樣做:

alter

table a add

index city_age(city,age)

練習問題:order by 與 limit 的用法

sort_buffer是啥?什麼引數控制?

全欄位排序執行流程?

row id排序執行流程?

優化方案?

mysql的optimizer_trace特性?

16 「order by」是怎麼工作的?

示例語句 select city,name,age from t where city 杭州 order by name limit 1000 mysql會給每個執行緒分配一塊記憶體用於排序,稱為sort buffer。city索引示意圖 通常情況這個語句的執行流程如下所示 初始化sort buff...

MySQL如何優化ORDER BY

某些情況中,mysql可以使用乙個索引來滿足order by子句,而不需要額外的排序。即使order by不確切匹配索引,只要where子句中的所有未使用的索引部分和所有額外的order by 列為常數,就可以使用索引。下面的查詢使用索引來解決order by部分 某些情況中,mysql可以使用乙個...

MySQL 優化 ORDER BY 優化

本文翻譯自mysql 官網 order by optimization,mysql 版本 5.7。這一部分描述了mysql何時會使用索引來滿足order by子句,filesort 操作會在索引不能生效的時候被用到,以及優化器對order by的執行計畫資訊。order by後面有沒有跟著limit...