MySQL高性能的索引策略(四)mysql
使用索引扫描来作排序sql
mysql有两种方式能够生成有序的结果:经过排序操做;或者经过索引顺序扫描;若是explain出来的type列的值为index,则说明mysql使用了索引扫描来作排序(不要和Extra 列的“using index”搞混淆了)。性能
扫描索引自己是很快的,由于只需从一条记录移动到紧接着的下一条记录。但若是索引不能覆盖查询所需的所有列,那就不得不每扫描一条索引记录就得回表查询一次对应的行。这基本上都是随机IO,所以按索引顺序读取数据的速度一般比顺序的全表扫描慢,尤为是在IO密集型的工做负载时。spa
mysql可使用同一个索引既知足排序,又用于查找行。所以若是可能,设计索引时应该尽量的知足这两种任务。设计
只有当索引的列的顺序和order by子句的顺序彻底一致,而且全部列的排序方向(倒序和正序)都同样时,mysql才能使用索引来对结果作排序。code
若是查询须要关联多张表,则只有order by子句引用的字段所有为第一个表时,才能使用索引来作排序。排序
order by子句和查找型查询的限制时同样的:须要知足索引的最左前缀的要求;不然,mysql都须要执行排序操做,而没法利用索引排序。索引
有一种状况下order by子句能够不知足索引的最左前缀要求,就是前导列为常量的时候。it
若是where子句或者join子句中对这些列指定了常量,就能够弥补索引的不足。table
> explain select id from article where title = 'hello world' order by shortName asc ******************** 1. row ********************* id: 1 select_type: SIMPLE table: article type: ref possible_keys: idx_short_name_title key: idx_short_name_title key_len: 257 ref: const rows: 5 Extra: Using where; Using index 1 rows in set
就如上面这个sql语句同样,虽然order by子句不能知足索引的最左前缀的要求,也能够用于查询排序,这是由于索引的第一列被指定为一个常数。就是 title = 'hello world';
就如上面的结果显示的那样,在explain的结果中,没有出现using filesort。
咱们来对照一下区别,
> explain select id from article order by title asc ******************** 1. row ********************* id: 1 select_type: SIMPLE table: article type: index possible_keys: key: idx_short_name_title key_len: 514 ref: rows: 5 Extra: Using index 1 rows in set
order by的列和索引的列的顺序一致。没有出现using filesort。
> explain select id from article order by shortName asc ******************** 1. row ********************* id: 1 select_type: SIMPLE table: article type: index possible_keys: key: idx_short_name_title key_len: 514 ref: rows: 5 Extra: Using index; Using filesort 1 rows in set
order by的列的顺序和索引列的顺序不一致,因此出现using filesort。
可是当查询的列不能所有被索引覆盖时,虽然指定索引列的前导列为常量,order by列的顺序和索引列其他的一致,但也是会出现using filesort。
> explain select id,totalView from article where title = 'hello world' order by shortName asc ******************** 1. row ********************* id: 1 select_type: SIMPLE table: article type: ALL possible_keys: idx_short_name_title key: key_len: ref: rows: 5 Extra: Using where; Using filesort 1 rows in set
==========END==========