mysql什麼時候會發生file sort

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

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。