https://blog.csdn.net/weixin_43767015/article/details/119568539
MySQL可以通过排序操作或者按索引顺序扫描这两种方式来排序。如果EXPLAIN的type列的值为“index”,则说明MySQL使用了索引扫描来做排序。
MySQL可以使用同一个索引既满足排序,又用于查找行,只有当索引列的顺序和ORDER BY字句的要求顺序是一致的,并且所有列的排序方向(倒序或正序时)MySQL才能够使用索引来对结果进行排序。
如果查询需要关联多张表, 则只有当 ORDER BY 子句引用的字段全部为第一个表时,才能使用索引做排序。 ORDER BY 子句和查找型查询的限制是一样的:需要满足索引的最左前缀的要求。否则, MySQL都需要执行排序操作,而无法利用索引排序。
一个例外是,如果前导列为常量的时候,如果WHERE或者JOIN字句中对这些列指定了常量,就可以弥补上面的不足。
一个多列索引(a,b,c),使用如下查询:
SELECT b, c, d FROM tablenames WHERE a = 123 ORDER BY b,c;
因为索引的第一列提供了常量,从而可以使用第二列开始进行排序,将三个列组合在一起,就行形成了索引的最左前缀。下面这个SQL也能使用排序:
…… WHERE a = 123 ORDER BY b DESC;
下面的SQL也能使用排序,因为ORDER BY的两列就是索引的最左前缀:
…… WHERE a > 123 ORDER BY a , b;
下面的SQL不能使用排序,因为ORDER BY使用了两种不同的排序方向:
…… WHERE a = 123 ORDER BY a DESC, b ASC;
下面的SQL不能使用排序,因为ORDER BY使用了一个不在索引中的列:
…… WHERE a = 123 ORDER BY b, d;
下面的SQL不能使用排序,因为WHERE和ORDER BY的列不满足最左前缀:
…… WHERE a = 123 ORDER BY c;
下面的SQL不能使用排序,因为WHERE的第一列上是范围条件,所以MySQL无法使用其他索引列: