大家好,我是 Snow Hide,作为《MySQL 实战》这个专栏的学员之一,这是我打卡的第 59 天,也是我第 121 次进行这种操作。
今天我温习了该专栏里一篇叫《“order by”是怎么工作的?》的文章。
关键词总结:全字段排序(语句的执行流程、MySQL 需要 12 个临时文件来做排序的原因)、row_id(指定排序的行数据长度后所采用的另一种算法、由于行数据长度过短导致排序结果少了 city 和 age 后整个执行的流程)、全字段排序 VS rowid 排序(创建 city 和 name 联合索引、city 满足一个值之后name 的值就一定是有序的、创建 city、name 和 age 联合索引、对于 city 字段值相同的行来说 name 字段的值递增也是递增排序)。
所学总结:
全字段排序
CREATE TABLE `t` (
`id` int(11) NOT NULL,
`city` varchar(16) NOT NULL,
`name` varchar(16) NOT NULL,
`age` int(11) NOT NULL,
`addr` varchar(128) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `city` (`city`)
) ENGINE=InnoDB;
select city,name,age from t where city='杭州' order by name limit 1000 ;
语句的执行流程
- 初始化 sort_number,确定放入 name、city、age 这三个字段;
- 从索引 city 找到第一个满足 city=‘杭州’ 条件的主键 id;
- 到主键 id 索引取出整行,取 name、city、age 三个字段的值,存入 sort_buffer 中;
- 从索引 city 取下一个记录的主键 id;
- 重复步骤 3、4 直到 city 的值不满足查询条件为止;
- 对 sort_buffer 中的数据按照字段 name 做快速排序;
- 按照排序结果取前 1000 行返回给客户端。
MySQL 需要 12 个临时文件来做排序的原因
MySQL 将需要排序的数据分成 12 份,每一份单独排序后存在这些临时文件中。然后把这 12 个有序文件再合并成一个有序的大文件。
row_id
指定排序的行数据长度后所采用的另一种算法
SET max_length_for_sort_data = 16;
max_length_for_sort_data
是 MySQL 专门控制用于排序的行数据长度的一个参数。
由于行数据长度过短导致排序结果少了 city 和 age 后整个执行的流程
- 初始化 sort_buffer,确定放入两个字段,即 name 和 id;
- 从索引 city 找到第一个满足 city=‘杭州’ 条件的主键 id;
- 到主键 id 索引取出整行,取 name、id 这两个字段,存入 sort_buffer 中;
- 从索引 city 取下一个记录的主键 id;
- 重复步骤 3、4 直到不满足 city=‘杭州’ 条件位置;
- 对 sort_buffer 中的数据按照字段 name 进行排序;
- 遍历排序结果,取前 1000 行,并按照 id 的值回到原表中取出 city、name 和 age 三个字段返回客户端。
全字段排序 VS rowid 排序
创建 city 和 name 联合索引
alter table t add index city_user(city, name);
city 满足一个值之后name 的值就一定是有序的
- 从索引(city,name)找到第一个满足 city=‘杭州’ 条件的主键 id;
- 到主键 id 索引取出整行,取 name、city、age 三个字段的值,作为结果集的一部分直接返回;
- 从索引(city,name)取下一个记录主键 id;
- 重复步骤2、3,直到查到第 1000 条记录,或者是不满足 city=‘杭州’ 条件时循环结束。
创建 city、name 和 age 联合索引
alter table t add index city_user_age(city, name, age);
对于 city 字段值相同的行来说 name 字段的值递增也是递增排序
- 从索引(city,name,age)找到第一个满足 city=‘杭州’ 条件的记录,取出其中的 city、name 和 age 这三个字段的值,作为结果集的一部分直接返回;
- 从索引(city,name,age)取下一个记录,同样取出这三个字段的值,作为结果集的一部分直接返回;
- 重复执行步骤 2,直到查到第 1000 条记录,或者是不满足 city=‘杭州’ 条件时循环结束。
末了
重新总结了一下文中提到的内容:MySQL 里 order by 语句的几种算法流程、每个语句的排序实现、每个语句的执行对系统资源的消耗。