MySQL处理排序有两种方式:全字段排序与rowid排序
全字段排序
查询分析器决策是否需要排序,如果需要的化,在server层的线程中分配一块内存,成为sort_buffer)
1)初始化sort_buffer, 把所有查询的字段放入sort_buffer
2) 依次通过索引或主表上取出所有字段放入到sort_buffer(server层,调用存储层接口获取数据)
3) 执行sort_buffer排序
4)返回结果集(可能有limit)
rowid 排序
解决sort_buffer放入字段太多的问题,导致实际的数据行放不下
max_length_for_sort_data,是 MySQL 中专门控制用于排序的行数据的长度的一个参数。它的意思是,如果单行的长度超过这个值,MySQL 就认为单行太大,要换一个算法,换成rowid排序
1)rowid排序只放入排序字段与主键ID到sort_buffer中,然后通过存储层接口取出 排序字段与ID到sort_buffer中
2)循环执行完成后,直接基于排序字段做排序
3)完成后,取出ID 列表(如果有limit,只取limit之内的),回表查询:相关的字段。
基于索引本身的有序性
1) 组合索引
合理设计组合索引:idx_city_name(city,name)
select * from t where city in ('杭州',"苏州") order by name limit 100;
这种情况仍然无法使用索引的有序,需要server层排序
2)覆盖索引或组合索引
idx_city_name(city,name) 都无需二次排序
select city,name from t where city = 杭州 order by name limit 100;
select * from t where city = 杭州 order by name limit 100;