天天看點

mysql優化之 ORDER BY Optimization

Use of Indexes to Satisfy ORDER BY

在某些情況下,MySQL可以使用索引來滿足ORDER BY子句,以避免執行filesort操作時涉及的額外排序。

如果所有未使用的索引部分和所有額外的ORDER BY字段,在WHERE子句中都是和常量比較,那麼即使ORDER BY字段與索引不完全比對,也可以使用索引。假設(key_part1,key_part2)上有索引。以下查詢将使用索引來處理ORDER BY部分:

mysql優化之 ORDER BY Optimization

如果查詢混合使用ASC和DESC,則優化器也可以在列上使用索引,如果索引也使用相應的混合ascending and descending (升序列和降序列):

mysql優化之 ORDER BY Optimization

如果key_part1是descending 且key_part2是ascending,則優化器也可以在(key_part1,key_part2)上使用索引。如果key_part1為升序且key_part2為降序,則優化器也可以在這些列上使用索引(使用反向掃描)。請參見第8.3.13節“ Section 8.3.13, “Descending Indexes”

在某些情況下,MySQL不能使用索引來解析ORDER BY,盡管它仍然可以使用索引來查找比對WHERE子句的行。例子:

mysql優化之 ORDER BY Optimization
  • 查詢連接配接多個表,并且ORDER BY中的列不是全部來自用于檢索行的第一個nonconstant table。 (第一個nonconstant table是指EXPLAIN輸出中第一個 join type不是 

    const類型的表

  • 具有不同的ORDER BY和GROUP BY表達式的查詢。

用于排序的索引的可用性可能受使用列别名影響。假設列t1.a有索引。在下面的語句中,select清單中的列名是a。它引用t1.a,就像在ORDER BY中引用a一樣,是以可以使用t1.a上的索引:

mysql優化之 ORDER BY Optimization

在下面的語句中,select語句清單中列的名稱也是a,但它使用的是别名。它引用ABS(a),就像在ORDER BY中引用a一樣,是以t1.a上的索引不能被使用:

mysql優化之 ORDER BY Optimization

在以下語句中,ORDER BY引用的名稱不是select語句清單中列的名稱。但是在t1中有一列名為a,是以ORDER BY引用t1.a并且可以使用t1.a上的索引。 (當然,得到的排序順序可能與ABS(a)的順序完全不同。)

mysql優化之 ORDER BY Optimization

以前(MySQL 5.7及更低版本),沒有顯式指定ASC或DESC辨別符的GROUP BY預設情況下是隐式排序的。在MySQL 8.0中,如果查詢包含GROUP BY而沒有顯式指定ASC或DESC訓示符,則隻有在需要對分組進行排序時才會對結果進行排序。在末尾指定ORDER BY NULL以禁止隐式排序(如前所述)不再需要。但是,查詢結果可能與以前的MySQL版本不同。要生成給定的排序順序,請提供ORDER BY子句。