问题:如果我们排序的时候,不能直接通过有序的索引直接返回排序数据,需要通过内存或者文件排序时,用explain关键字来解释sql时辉出现using filesort,进行了额外的排序,这样会使得排序的效率不高,通常是我们优化的重点方向
mysql排序的过程
1.如果排序的字段是索引,那么查询的数据直接就是有序的,不需要再进行二次的排序
2.如果排序的字段没有索引,那么查询出来的数据会进入一个order_suffer的内存空间中进行排序。
2.1 order_suffer是给排序线程分配的一块内存空间,大小为256k,如果需要排序的数据大于256k,那么会在硬盘(文件中进行排序)。内存排序的效率肯定是要高于硬盘的,这也是Mysql的设计理念,能用内存的就用内存。
2.2 全字段排序与rawId排序,为了防止每一行的记录过大,导致很容易达到order_suffer的阈值,所以加了一个max_length_for_order_suffer的阈值来限制查出来结果的单行最大值,如果小于这个阈值,会使用全字段排序,也就是在order_suffer中有全部要返回的字段和排序的字段,这样排完序以后就可以直接返回给客户端了,如果大于这个阈值,那么order_suffer中就只有待排序字段和rawId,这样做的目的是由于单行记录过大,防止order_suffer很快被填充完,需要使用磁盘来进行排序,这样排完序之后,还需要通过rawId来回表,查询出所有需要返回的字段信息。所以全字段排序比rawId排序的方式少了一次回表的操作,效率就会更高。
解决方案:
1.将要排序的字段加上索引,这样查询出来的数据直接就是有序的,不需要再进行排序
2.索引的维护成本很高,如果不好加索引,那么尽量不要使用select *的方式,只查询出需要的字段,这样可以减少需要查询的数据量,可以使用全字段排序和内存排序。
3.适当调整order_suffer的值,避免文件排序
4.适当调整max_length_for_order_suffer的值,避免rawId排序的方式