更多知識,請移步我的小破站: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即使沒有過濾條件用到索引,也可以直接使用索引。