mysql什麼時候會發生file sort

my日常work發表於2022-03-09

      看了網上很多排名很靠前的部落格,發現好多都講錯了!我開始按照部落格來,沒有懷疑,直到自己試了一下才發現是錯的。

file sort在面試中有時候會問到,這個其實挺能區分是不是真的瞭解order by的執行了。大部分人會以為file sort是檔案排

序,其實不要看字面意思,並不是檔案排序!只不過是表示排序沒有用到索引。其實不自己試驗,挺難想到的。

我這裡使用mysql5.7試驗了幾種情況,供大家參考.

首先建立的表欄位是 id, username, password, age, gender,其中id是自增的主鍵索引,(username, password, age)是聯合索引

  1. 第一種情況:查詢語句不帶where條件過濾

  1) select * from user_info order by username。使用了file sort,查詢的欄位不在username聯合索引中或者也不是主鍵id。會產生file sort。

         等價於 select gender from user_info order by username,也會產生file sort!那 select id from user_info order by username,會不會產生file sort呢?是不會的,

         因為mysql的b+樹葉子節點也是儲存了主鍵資訊的。

      

  2)那這樣呢 select password from user_info order by username; 這個是不會產生file sort的!因為查詢的欄位在聯合索引中。

      

    3) 上面兩種情況都是order by後面的欄位都是符合最左字首原則,沒有索引失效。沒有索引失效,是看查的欄位是不是在索引中!那索引失效會不會出現file sort呢?

    select username from user_info order by password, username;  //索引失效了

  

   

  2. 第二種情況:查詢條件帶有where條件過濾

    其實帶where條件也主要是看order by後面的欄位用的索引。如果order by後面的欄位不符合最左字首原則,那麼肯定是會產生file sort的。如果order by用到了索引

    則看select 出來的欄位是否是在索引頁中儲存的資訊,如果是索引中的資訊則不會file sort。(這裡有幾個特殊情況,是mysql引擎的優化產生的)

    1)select * from user_info where username = '1' order by username;

   這個where條件是username,等值查詢。再去order by username。沒必要,所以mysql會把order by 去掉。order by都去掉了,肯定不會file sort了。

  

 

   2)select age from user_info where age = '1' order by username;

   這個是不會的,因為直接根據聯合索引去查詢 password = '1' 的,取出來的所有資料自然是根據username排序的(索引排好了序)。不需要file sort。

     

  3) select gender from user_info where age = 1 order by username; 因為gender欄位不在order by使用的欄位中,所以需要file sort。

     

 

      4)select password from user_info where password = '10' order by username, age;

  首先看select出來的欄位在不在order by所使用的索引中,這個是在的。所以排除第一種情況。繼續分析。mysql先去這個索引中找出password 為 '10'的資料行,

      極大情況有多條,在索引上取出的資料,看是不是符合先按username排序,再按age排序呢?是的,因為從索引上遍歷取password='10'的資料時候,取出來的

  資料天然是按username先排序的(索引特性),password是等值的情況下,再按age排序的。所以取出來的資料已經排序了。

  

 

  這一塊一定要注意啊!!!網上很多說mysql使用file sort看order by欄位有沒有符合最左匹配,是錯的!主要是看mysql在where條件上是否使用

  索引(select (索引中的欄位)where 索引中的欄位),使用了索引的欄位,會using index去查出資料。然後再看是否取出來的資料是否是排好序的。

  插曲,slect age from user_info where age = 1;會使用索引嗎?答案是會的,這個不符合最左字首匹配,但是select出來的欄位是在索引中的。

  5)select password from user_info where age = 1 order by password, username;

  這個是會用到索引的,因為select password的欄位在索引列中,並且where條件也是age也是在這個索引中的。

  但是在B+樹索引上,根據age取出來的資料,看看是不是先password,再username排序呢?顯然不是,所以會發生file sort。

  

 

 

總結:什麼時候會發生file sort呢?

  首先,看這個是不是走索引,是不是在索引上查詢資料。如果沒有使用索引,那麼會file sort。因為沒有在索引上取資料,那麼取出來的資料就是無序的。

  需要file sort。如果使用了索引。取出來的資料看是否是滿足order by後面的排序欄位要求,如果滿足。則不需要file sort。如果不滿足,則需要file sort。

相關文章