MySQL有两种方式可以生成有序的结果:通过排序操作;或者按索引顺序扫描;如果EXPLAIN出来的type列的值为:“index“,则说明MySQL使用了索引扫描来做排序
扫描索引本身是很快的,因为只需要从一条索引记录移动到紧接着的下一条记录。但如果索引不能够覆盖查询所需的所有列,那就不得不每扫描一条索引记录就会表查询一次对应的行。这基本是上随机I/O,因此按索引顺序读取数据的速度通常要比顺序地全表扫描慢。
MySQL可以使用同一个索引既满足排序,有用于查找行。因此,如果可能,设计索引时应该尽可能的同时满足这两种任务,这样是最好的。
只有查找顺序与索引顺序一致时才会使用索引排序
只有当索引的顺序和ORDER BY子句的顺序完全一致,并且所有列的排序方向都一样时,MySQL才能使用索引来对结果做排序。
关联查询索引使用规则
如果查询要关联多张表,则只有当ORDER BY子句引用的字段全部为第一个表时,才能使用索引做排序。
ORDER BY使用索引排序要求与查询型语句要求一致
ORDER BY子句和查找型查询的限制是一样的:需要满足索引的最左前缀的要求;否则,MySQL需要执行排序操作,而无法利用索引排序
当前导列为常量时,就不需要满足最左前缀比较
被指定为一个常数就是说 rental_date这一列的值被指定为‘2005-05-25’,不再需要进行排序
还有更多可以使用索引排序的查询示例:
这个ORDER BY使用的两列是索引的最左前缀
... WHERE rental_date > '2005-05-25' ORDER BY rental_date,inventory_id;
复制代码
下面这些是不能使用索引排序的查询:
排序方向与索引不一致
... WHERE rental_date='2005-05-25' ORDER BY inventory_id DESC,customer_id ASC
复制代码出现了索引之外的列
... WHERE rental_date='2005-05-25' ORDER BY customer_id
复制代码WHERE和ORDER BY无法组成索引最左前缀
...WHERE rental_date='2005-05-25' ORDER BY customer_id
复制代码第一列使用了范围查询,所以无法使用索引的其余列
... WHERE rental_date > '2005-05-25' ORDER BY inventory_ids,customer_id;
复制代码在inventory_id上有多个等于条件。对于排序来说,也是一种范围查询
... WHERE rental_date='2005-05-25' AND inventory_id IN(1,2) ORDER BY customer_id;
复制代码