某些情況中,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;