MySQL如何優化ORDER BY

某些情況中,MySQL可以使用一個索引來滿足ORDER BY子句,而不需要額外的排序。

即使ORDER BY不確切匹配索引,只要WHERE子句中的所有未使用的索引部分和所有額外的ORDER BY 列爲常數,就可以使用索引。下面的查詢使用索引來解決ORDER BY部分:

某些情況中,MySQL可以使用一個索引來滿足ORDER BY子句,而不需要額外的排序。
SELECT * FROM t1 
    ORDER BY key_part1,key_part2,... ;
SELECT * FROM t1 
    WHERE key_part1=constant 
    ORDER BY key_part2;
SELECT * FROM t1 
    ORDER BY key_part1 DESC, key_part2 DESC;
SELECT * FROM t1
   WHERE key_part1=1 
    ORDER BY key_part1 DESC, key_part2 DESC;
在某些情況下,MySQL不能使用索引來解決ORDER BY,儘管它仍然使用索引來找到匹配WHERE子句的行。這些情況包括:
1. 讀行匹配WHERE子句的行,如前面所示。

2. 對於每個行,記錄構成排序關鍵字和行位置的一系列值,並且記錄查詢需要的列。

3. 根據排序關鍵字排序元組

4. 按排序的順序檢索行,但直接從排序的元組讀取需要的列,而不是再一次訪問表。

爲了避免速度變慢,該優化只用於排序元組中的extra列的總大小不超過max_length_for_sort_data系統變量值的時候。

如果想要增加ORDER BY的速度,首先看是否可以讓MySQL使用索引而不是額外的排序階段。如果不能,可以嘗試下面的策略:

1. 增加sort_buffer_size變量的大小。
 
2. 增加read_rnd_buffer_size變量的大小。
 
3. 更改tmpdir指向具有大量空閒空間的專用文件系統。
默認情況下,MySQL排序所有GROUP BY col1,col2,…查詢的方法如同在查詢中指定ORDER BY col1,col2,…。如果顯式包括一個包含相同的列的ORDER BY子句,MySQL可以毫不減速地對它進行優化,儘管仍然進行排序。如果查詢包括GROUP BY但你想要避免排序結果的消耗,你可以指定ORDER BY NULL禁止排序。例如:

INSERT INTO foo
SELECT a, COUNT(*) FROM bar GROUP BY a ORDER BY NULL;




發佈了27 篇原創文章 · 獲贊 59 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章