MySQL優化——Order By關鍵字優化

在使用order by時,經常出現Using filesort,因此對於此類sql語句需盡力優化,使其儘量使用Using index。

1.準備
1.1 創建test表。

drop table if exists test;
create table test(
id int primary key auto_increment,
c1 varchar(10),
c2 varchar(10),
c3 varchar(10),
c4 varchar(10),
c5 varchar(10)
) ENGINE=INNODB default CHARSET=utf8;
 
insert into test(c1,c2,c3,c4,c5) values('a1','a2','a3','a4','a5');
insert into test(c1,c2,c3,c4,c5) values('b1','b2','b3','b4','b5');
insert into test(c1,c2,c3,c4,c5) values('c1','c2','c3','c4','c5');
insert into test(c1,c2,c3,c4,c5) values('d1','d2','d3','d4','d5');
insert into test(c1,c2,c3,c4,c5) values('e1','e2','e3','e4','e5');


1.2 創建索引。


 
2.根據Case分析order by的使用情況
Case 1:


分析:

①在c1,c2,c3,c4上創建了索引,直接在c1上使用範圍,導致了索引失效,全表掃描:type=ALL,ref=Null。因爲此時c1主要用於排序,並不是查詢。

②使用c1進行排序,出現了Using filesort。

③解決方法:使用覆蓋索引。

Case 1.1:

分析:

排序時按照索引的順序,所以不會出現Using filesort。

Case 1.2:
分析:

出現了Using filesort。原因:排序用的c2,與索引的創建順序不一致,對比Case1.1可知,排序時少了c1(帶頭大哥),因此出現Using filesort。

Case 1.3:


分析:

出現了Using filesort。因爲排序索引列與索引創建的順序相反,從而產生了重排,也就出現了Using filesort。

Case 2:


 分析:

直接使用c2進行排序,出現Using filesort,因爲不是從最左列索引開始排序的(沒有帶頭大哥)。

Case 2.1:


分析:

排序使用了索引順序(帶頭大哥在),因此不會出現Using filesort。

Case 2.2:


分析:

雖然排序的字段列與索引順序一樣,且order by默認升序,這裏c2 desc變成了降序,導致與索引的排序方式不同,從而產生Using filesort。

 
3.總結
1.MySQL支持兩種方式的排序filesort和index,Using index是指MySQL掃描索引本身完成排序。index效率高,filesort效率低。

2.order by滿足兩種情況會使用Using index。

order by語句使用索引最左前列。
使用where子句與order by子句條件列組合滿足索引最左前列。
3.儘量在索引列上完成排序,遵循索引建立(索引創建的順序)時的最佳左前綴法則。

4.如果order by的條件不在索引列上,就會產生Using filesort。

5.提升order by速度的方式:

在使用order by時,不要用select *,只查詢所需的字段。
嘗試提高sort_buffer_size。
嘗試提高max_length_for_sort_data。
6.附上一張從視頻中截取出來的總結圖。

7.group by與order by很類似,其實質是先排序後分組,遵照索引創建順序的最佳左前綴法則。當無法使用索引列的時候,也要對sort_buffer_size和max_length_for_sort_data參數進行調整。注意where高於having,能寫在where中的限定條件就不要去having限定了。 
 

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