总的来说,在 mysql 中的order by有两种排序实现方式,一种是利用有序索引获取有序数据,另一种则是通过相应的排序算法,将取得的数据在内存中进行排序。
下面将通过实例分析两种排序实现方式及实现图解:
假设有 table a 和 b 两个表结构分别如下:
1 sky@localhost : example 01:48:21> show create table a\g
2
3 *************************** 1. row ***************************
4
5 table: a
6
7 create table: create table `a` (
8
9 `c1` int(11) not null default '0',
10
11 `c2` char(2) default null,
12
13 `c3` varchar(16) default null,
14
15 `c4` datetime default null,
16
17 primary key (`c1`)
18
19 ) engine=myisam default charset=utf8
20
21 sky@localhost : example 01:48:32> show create table b\g
22
23 *************************** 1. row ***************************
24
25 table: b
26
27 create table: create table `b` (
28
29 `c1` int(11) not null default '0',
30
31 `c2` char(2) default null,
32
33 `c3` varchar(16) default null,
34
35 primary key (`c1`),
36
37 key `b_c2_ind` (`c2`)
38
39 ) engine=myisam default charset=utf8
1、利用有序索引进行排序,实际上就是当我们 query 的 order by 条件和 query 的执行计划中所利用的 index 的索引键(或前面几个索引键)完全一致,且索引访问方式为 rang、 ref 或者 index 的时候,mysql 可以利用索引顺序而直接取得已经排好序的数据。这种方式的 order by 基本上可以说是最优的排序方式了,因为 mysql 不需要进行实际的排序操作。假设我们在table a 和 b 上执行如下sql:
1 sky@localhost : example 01:44:28> explain select a.* from a,b
2
3 -> where a.c1 > 2 and a.c2 5 and a.c2 = b.c2 order by a.c1\g
4
5 *************************** 1. row ***************************
6
7 id: 1
8
9 select_type: simple
10
11 table: a
12
13 type: range
14
15 possible_keys: primary
16
17 key: primary
18
19 key_len: 4
20
21 ref: null
22
23 rows: 3
24
25 extra: using where
26
27 *************************** 2. row ***************************
28
29 id: 1
30
31 select_type: simple
32
33 table: b
34
35 type: ref
36
37 possible_keys: b_c2_ind
38
39 key: b_c2_ind
40
41 key_len: 7
42
43 ref: example.a.c2
44
45 rows: 2
46
47 extra: using where; using index
我们通过执行计划可以看出,mysql实际上并没有进行实际的排序操作,实际上其整个执行过程如下图所示: