MySQL中,有两种方式生成有序结果集:一是使用filesort,二是按索引顺序扫描。利用索引进行排序操作是非常快的,而且可以利用同一索引同时进行查找和排序操作。当索引的顺序与ORDER BY中的列顺序相同且所有的列是同一方向(全部升序或者全部降序)时,可以使用索引来排序。如果查询是连接多个表,仅当ORDER BY中的所有列都是第一个表的列时才会使用索引。其它情况都会使用filesort。
MySQL索引通常是被用于提高WHERE条件的数据行匹配或者执行联结操作时匹配其它表的数据行的搜索速度。
MySQL也能利用索引来快速地执行ORDER BY和GROUP BY语句的排序和分组操作。
通过索引优化来实现MySQL的ORDER BY语句优化:
create table actor(actor_id int unsigned NOT NULL AUTO_INCREMENT,name varchar(16) NOT NULL DEFAULT '',password varchar(16) NOT NULL DEFAULT '',PRIMARY KEY(actor_id), KEY (name)) ENGINE=InnoDBinsert into actor(name,password) values('cat01','1234567');insert into actor(name,password) values('cat02','1234567');insert into actor(name,password) values('ddddd','1234567');insert into actor(name,password) values('aaaaa','1234567'); |
mysql> explain select actor_id from actor order by actor_id /G |
*************************** 1. row *************************** id: 1 select_type: SIMPLE table: actor type: indexpossible_keys: NULL key: PRIMARY key_len: 4 ref: NULL rows: 4 Extra: Using index1 row in set (0.00 sec) |
mysql> explain select actor_id from actor order by password /G |
*************************** 1. row *************************** id: 1 select_type: SIMPLE table: actor type: ALLpossible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 4 Extra: Using filesort1 row in set (0.00 sec) |
mysql> explain select actor_id from actor order by name /G |
*************************** 1. row *************************** id: 1 select_type: SIMPLE table: actor type: indexpossible_keys: NULL key: name key_len: 18 ref: NULL rows: 4 Extra: Using index1 row in set (0.00 sec) |
下面来罗列一些常见的索引对ORFER BY的优化情况:
1、如果一个SQL语句形如:
SELECT [column1],[column2],…. FROM [TABLE] ORDER BY [sort]; |
在[sort]这个栏位上建立索引就可以实现利用索引进行order by 优化。
2、WHERE + ORDER BY的索引优化,形如:
SELECT [column1],[column2],…. FROM [TABLE] WHERE [columnX] = [value] ORDER BY [sort]; |