Using filesort

发布时间 2023-12-17 23:48:11作者: 李若盛开
  • MySQL支持两种方式的排序filesort和index,Using index是指MySQL扫描索引本身完成排序

  • 如果order by的条件不在索引列上,就会产生Using filesort

Using filesort表示在索引之外,需要额外进行外部的排序动作。当MySQL无法使用索引完成排序时,它会将结果集保存到临时文件中,然后再进行排序,这个过程就是Using filesort。

由于没有合适的索引,MySQL无法使用索引完成排序,因此会使用Using filesort进行排序。【查询出所有数据再进行排序】

需要注意的是,Using filesort会占用大量的磁盘空间和CPU资源,因此应该尽量避免使用。可以通过添加合适的索引或者优化查询条件来避免Using filesort的使用。

一般来说,执行计划中如果Extra字段中值为Using filesort时,那么type字段(查询类型)一般为index或ALL。(两者都是查询所有数据,index与ALL区别为index类型只遍历索引树。通常比ALL快,因为索引文件通常比数据文件小。Index与ALL虽然都是读全表,但index是从索引中读取,而ALL是从硬盘读取)

SQL 性能优化 explain 中的 type:至少要达到 range 级别,要求是 ref 级别,如果可以是 consts 最好。

这种情况下,Mysql会给sql语句的执行过程提供一块缓存区 sort buffer ,这个区域的默认大小为1M,放在内存中,但可通过max_length_for_sort_data参数修改。

文件排序是通过相应的排序算法,将取得的数据在内存中进行排序:MySQL需要将数据在内存中进行排序,所使用的内存区域也就是我们通过sort_buffer_size系统变量所设置的sort buffer(排序区)。这个sort buffer是每个Thread独享的,所以说可能在同一时刻在MySQL中可能存在多个sort buffer内存区域。

磁盘的临时文件,MySQL会采用归并排序的思想,把要排序的数据分成若干份,每一份数据在内存中排序后会放入临时文件中,最终对这些已经排序好的临时文件的数据再做一次合并排序。【分治的思想】

以下场景都会出现using filesort:

1)order by的字段顺序与索引字段顺序不一致
2)order by的字段没有遵循最左前缀原则
3)order by字段非连续
4)order by字段升序、降序混合

总结:

1)对于 order by 没有用到索引时,explain 中 Extra 字段大概是会出现 using filesort
2)出现 using filesort 的时候也不用太慌张,如果本身数据量不大,比如也就几十条数据,那么在 sort buffer 中使用快排也是很快的
3)如果数据量很大,超过了 sort buffer 的大小,那么是要进行临时文件排序的,也就是归并排序,这部分是由MySQL优化器决定
4)如果查询的字段很多,想要尽量避免使用临时文件排序,可以尝试设置下 max_length_for_sort_data 字段的大小,让其小于所有查询字段长度的总和,这样放入或许可以避免,但是会多一次回表操作
5)实际业务中,可以给经常要查询的字段组合建立个联合索引,这样既不用回表也不需要单独排序,但是联合索引会占用更多的存储和开销
6)大量数据查询的时候,尽量分批次,提前 explain 来观察 sql 的执行计划是个不错的选择