order by
sql
#city为索引
select city,name,age from zx where city='杭州' order by name limit 1000
sort_buffer
Mysql进行排序的时候会分配每个线程分配一块内存用于排序
全字段排序
过程
1.首先会根据要查找的字段初始化sort_buffer,放入city,name,age字段
2.然后根据city索引找到所有满足city=‘杭州'的数据
3.然后根据之前的查询结果,根据主键id取出需要的数据存入sort_buffer里面
4.对sort_buffer中的数据按字段名name进行快速排序
5.最后取前1000条返回结果集
分析
从查询流程中我们知道,真正排序的过程其实就是第4步
第4步,其实还涉及到内存和的问题
#sort_buffer_size,就是MySQL为排序开辟的内存
1.如果数据量不大,可以用sort_buffer完全存下,那么排序都在内存中进行
2.如果数据量太大,sort_buffer存不下,就会利用磁盘的临时文件辅助排序
rowid排序
这个排序是专门针对单行数据很大的情况的
max_length_for_sort_data
排序单行数据最大长度,如果超过这个最大长度就会选用rowid进行排序
过程
1.初始化sort_buffer,放入主键id和需要排序的字段
2.按照索引city,把满足条件主键id取得
3.更具主键id取出整行数据,把id和name存入sort_buffer
4.对sort_buffer里面的数据按照name排序
5.最后根据排序结果,取出前1000行,并按照id取出city,name,age三个字段返回客户端
全字段 VS rowid
其实观察rowid的排序过程,我们可以轻易的发现,数据查询的过程变的更麻烦了,但是排序都是在内存中进行的,这就是它的主要目的,如果涉及到磁盘的读写,效率损失的就更厉害了
MySQL的设计思想
如果内存够用,就要多利用内存,尽量减少磁盘的访问
为啥要排序?
这就是排序的核心问题,因为查询出来的数据是无序的,所以我们要对数据排序,所以如果我们实现查询出来的数据就有序的话,可以直接避免上述的排序过程,这样的效率才是最高的
但是涉及到数据有序问题,那不避免的就是索引问题,索引也是需要成本的,所以这又是一场效率和成本的权衡问题,要对特定的问题,具体分析
关于索引,可以使用联合索引或者覆盖索引等办法