前置知識
Using filesort:表示需要用到 sort buffer 記憶體空間進行排序
sort buffer 是一塊可調整的記憶體空間,如果需要排序的資料量太大而空間不夠,將用到磁盤臨時檔案來排序,效率很低
什么情況下會用到 sort buffer 來排序?
不能根據索引直接知道排序結果,就需要用到 sort buffer
排序的執行情況?
表T:id (primary key), city (key), name, age 等欄位
explain select city,name,age from T where city = 'gz' order by name;
-- 走了索引(但是是非覆寫索引),需要排序,需要進行回表查詢
-- Using index condition; Using filesort
這個 SQL陳述句可以知道,不能根據索引直接知道排序結果,所以需用到 sort buffer 排序
● 全欄位排序 執行流程
初始化 sort buffer,確定此記憶體中需要存放的欄位
到 city 欄位索引上找到匹配的第一行
回表查詢,把 city,name,age 存到 sort buffer 中
重復上述兩步,直到不滿足 where 條件(city 索引上找到一行不滿足的資料)
對 sort buffer 中的資料排序
回傳結果集給客戶端
● rowid 排序執行流程
排序前,會檢測放入 sort buffer 中的欄位的長度,如果超過最大單行長度值(可調),那么就會只放rowid 和 需要排序的欄位
explain select city,name,age from T where city = 'gz' order by name;
-- 走了索引(但是是非覆寫索引),需要排序,需要進行回表查詢
-- Using index condition; Using filesort
MySQL如果檢測到 city,name,age 等欄位超過了最大單行長度值,就會只把 id, name 等欄位放入 sort buffer 中
執行流程
相比全欄位排序,基本流程一致,存入 sort buffer 中的欄位變少了,在排序完后,又要回表查詢然后回傳結果集,效率變低了
這個排序機制是為了保證盡可能的使用 sort buffer 記憶體排序,減少記憶體存放的資料行,那么存放的資料量就更多,從而降低/不適用磁盤臨時檔案排序
如何優化?
可以這樣創建普通索引 (city, name),那么執行上述 SQL 陳述句時,不會用到記憶體排序
執行流程
到 city 欄位索引上找到匹配的第一行
回表查詢,把 city,name,age 作為 結果集 的一部分直接回傳
重復上述兩步,直到不滿足 where 條件
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/543110.html
標籤:其他
