MySQL 使用索引扫描来做排序

2016-09-14 15:54:23   数据库

  mysql  

声明

文章内容出自《高性能Mysql第三版》

MySQL有两种方式可以生成有序的结果:通过排序操作;或者按索引顺序扫描
如果explain出来的type列的值为index,则说明MySQL使用了索引来扫描做排序

MySQL可以使用同一个索引即满足排序,有用于查找行。所以如果可以,设计索引是应该尽可能地同时满足这两种任务。这样是最好的。

只有当所以的列顺序和order by字句顺序完全一致,并所有列的排序方向(倒序或者正序)都一样时,MySQL才能够使用索引来对结果做排序

如果查询需要关联多张表,则只有当order by字句引用的字段全为一个表时,才能使用索引做排序

order by 字句和查找型查询的限制是一样的。需要满足索引最左前缀的要求。否则,MySQL都需要执行排序操作。而无法使用索引来排序

有一种情况下order by字句可以不满足索引的最左索引的要求,就是前导列为常量的时候。如果where字句或者join字句中对这些列指定了常量。就可以弥补索引的不足

例如:
demo表的索引index1(a,b,c);

  1. select id,name from demo where a='10' order by b,c;
  2. /* 这时候,因为a指定的是一个常量,所以就可以是用索引index1·来排序,同理order by b 也是可以是用索引的 */
  3. select id,name from demo where a>10 order by a,b;
  4. /* 这时候也可以使用索引来排序 */
  5. /* 下列的SQL则无法是用索引来排序:*/
  6. select id,name from demo where a=10 order by b DESC,c ACS
  7. /* 使用了两种不同的排序方式*/
  8. select id,name from demo where a=10 order b,group_id
  9. /*因为排序中使用了一个不再索引的列*/
  10. select id,name from demo where a=10 order by c
  11. /*无法组合成最左索引 */
  12. select id,name from demo where a>10 order by b,c
  13. /*因为第一列是范围条件*/
  14. select id,name from demo where a=10 and b in(1,2,3) order by c
  15. /*因为b使用了in 也属于范围查询,所以无法使用索引 */