MySQL之排序分組的索引優化

更多知識,請移步我的小破站:http://hellofriend.top

排序優化

ORDER BY子句,儘量使用Index方式(索引)排序,避免使用FileSort方式(手工)排序。

技巧:無過濾,不索引;順序錯,必手工排序;方向反,必手工排序;
  • 要想Order BY使用到索引,必須要添加過濾條件(where子句對索引中的字段進行過濾,而且必須按照順序),Limit分頁也行。
  • 在SQL語句中的順序一定要和定義索引中的字段順序完全一致。
  • 要麼全升序、要麼全降序。有升有降無法使用索引。

案例

SELECT SQL_NO_CACHE * FROM emp WHERE age =30 AND empno <101000 ORDER BY NAME ;

可以看到,上面where條件中有範圍查詢,那麼後面的索引會失效。

那麼我們可以創建兩個索引,一個是idx_age_empno(避免不了Using filesort),另一個是idx_age_name(不能讓where條件充分用到索引),當這兩個索引同時存在的時候,MySQL會選擇誰作爲最優索引呢?會選擇讓where子句舒服的索引,即idx_age_empno

Using filesort有兩種排序算法

一種是單路排序,一種的雙路排序。

雙路排序

MySQL4.1 之前是使用雙路排序,字面意思就是兩次掃描磁盤,最終得到數據,讀取行指針和 orderby 列,對他們進行排序,然後掃描已經排序好的列表,按照列表中的值重新從列表中讀取對應的數據輸出。

從磁盤取排序字段,在 buffer進行排序,再從磁盤取其他字段。

簡單來說,取一批數據,要對磁盤進行了兩次掃描,衆所周知,I/O 是很耗時的,所以在 mysql4.1 之後,出現了第二種改進的算法,就是單路排序。

單路排序

從磁盤讀取查詢需要的所有列,按照 order by 列在 buffer 對它們進行排序,然後掃描排序後的列表進行輸出, 它的效率更快一些,避免了第二次讀取數據。並且把隨機 I/O 變成了順序 I/O,但是它會使用更多的空間,因爲它把每一行都保存在內存中了。

單路排序更快,因爲使用到了內存。

分組優化

Group By 使用索引的原則幾乎跟Order By一致 ,唯一區別是Group By即使沒有過濾條件用到索引,也可以直接使用索引。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章