orderby排序原理及性能优化
前⾔
排序是我们在写项⽬中经常⽤的sql语句的关键字。 往往order by ⽤不好的话也会对sql性能有⼀定的影响。我们现在就来介绍⼀下他的执⾏过程,并介绍⼀下优化。
正⾔
⾸先我们来举个例⼦,假设你要查询城市是”杭州“的所有⼈的名字,并且按照姓名排序返回前1000个⼈的姓名、年龄。
表定义:
这时,你的sql语句可以这么写:
这个语句看上去逻辑很清晰,我们还是需要看看他的sql执⾏过程。
执⾏过程⼀:全字段索引
我们需要在city上添加⼀个索引。 我们在执⾏explain命令来看看这个语句的执⾏情况。
Extra这个字段中的”Using filesort“ 表⽰的就是需要排序,MySql会给每个线程分配分配⼀块内存⽤于排序,称为sort_buffer。
下⾯是图⽰:
sort命令排序从图中可以看到,满⾜city=‘杭州’条件的⾏,是从ID_X到ID_(X+N)的这些记录。
通常情况下,这个语句执⾏流程如下所⽰:
1. 初始化sort_buffer, 确定放⼊name、city、age这三个字段;
2. 从索引city到第⼀个满⾜city=“杭州” 条件的主键id,也就是图中的ID_X;
3. 到主建id索引取出整⾏,取name、city、age 三个 字段的值,存⼊sort_buffer中;
4. 从索引city取下⼀个记录的主键id ;
5. 重复步骤3、4直到city的值不满⾜查询条件为⽌,对应的主键id也就是图中的ID_Y;
6. 对sort_buffer 中的数据按照字段name做快译排序;
7. 按照排序结果取前1000⾏返回给客户端;
我们暂且把这个排序过程,称为全字段排序,执⾏流程的⽰意图
图中“按name排序 ”这个动作,可能在内存中完成,也可能需要使⽤外部排序,这取决于排序所需的内
存和参数 sort_buffer_size; routId 排序
在上⾯这个算法过程⾥⾯,只对原表的数据读了⼀遍,剩下的操作都是在sort_buffer和临时⽂件中执⾏的。但这个算法有⼀个问题,如果查询返回的数据字段多,那么内存中放的数据就要分成多个临时⽂件,排序的性能就会很差。
修改参数 max_length_for_sort_data,是MySql中专门控制⽤于排序的⾏数据的长度的⼀个参数,它的意思是,如果单⾏的长度超过这个值 ,MySQL就认为单⾏太⼤,要换⼀个算法。
city,name,age这三个字段的定义总长度是36,我把max_length_for_sort_data设置为16,那么放⼊sort_buffer的字段只有要排序的列(即 name 字段 是order by 后⾯的关键字)和主键id。
但这时,排序的结果就因为少了city和age字段的值 ,不能直接返回了,整个执⾏的流程就变成 如下所⽰的样⼦:
1. 初始化sort_buffer,确定放⼊两个字段,即name和id;
2. 从索引city到第⼀个满⾜city='上海’条件的主键,也就是图中的ID_X;
3. 到主键id索引取出整⾏,取name、id这两个字段,存⼊sort_buffer中;
4. 从索引city取下⼀个记录的主键id;
5. 重复3、4步骤,直到到不city!=‘上海’;
6. 对sort_buffer中的数据按照name进⾏排序;
7. 遍历排序结果,取前1000⾏,并按照id的值回到原表中的city、name和age三个字段返回给客户端。
对排序进⾏优化
alter table t add index_city(city,name);
这样数据的索引就有按照name进⾏排序。 这样整个排序过程就变成了下⾯这样。
1. 从索引(city,name)到第⼀个满⾜city="杭州"条件的主键id;
2. 到主键id索引取出整⾏,取name、city、age三个字段的值,作为结果集的⼀部分直接返回。
3. 从当前索引取出⼀个索引值,id.
4. 重复2、3步。
在使⽤explain 来分析这个sql
可以看到extra字段中没有Using filesort了,也就是不需要排序了。
由于覆盖索引的原则,我们可以在进⾏优化。
alter table t add index_city(city,name,age);
在使⽤explain 对sql进⾏分析
发现使⽤Using index,表⽰的就是使⽤了覆盖索引,性能上会快很多。
总结
创建索引在添加和修改数据的时候是会对性能有损耗的, 在优化的时候要考虑使⽤的场景。
⽂中的内容借鉴了,极客时间中的Mysql的内容。
猿来⾐舍
这是博主开的淘宝⼩店,主要经营舒适保暖的服饰,有袜⼦、主题卫⾐、保暖⾐。欢迎⼤家选购。我们也在着⼿开发脚⼿架,到时候会做为商店福利的赠送给⽼⽤户
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论