可是从咱们的性能统计来看,全部的order by都是在内存中执行的,没有在硬盘上执行。mysql
将排序改到应用层排序,整个性能立马提升了不少。因而新的疑问就来了,难道mysql的排序性能这么差吗?算法
在http://forge.mysql.com/wiki/MySQL_Internals_Algorithms这里发现了mysql的排序算法原理。sql
mysql的filesort算法有两种,一种是最初的算法,在MySQL 4.1之前只有这种算法,另一种是改进的filesort算法,它出如今
MySQL 4.1之后(blob和text类型的字段不能采用这种改进算法)性能
最初的算法流程以下(简单起见,假设数据小于等于sort_buffer_size,详细能够见上面的url):
1.读取全部的知足条件的数据,只包含sort key和row pointer两种数据
2.在buffer中执行qsort排序
3.排完序后,再根据row pointer去读取相应的行数据url
从中能够看出,每次排序都须要读两次表,而根据row pointer去读表每每都是随机离散读的,全部其开销很是大。排序
改进后的算法是:
1.读取所须要的数据,包含sort key,row pointer和查询所须要访问的字段
2.根据sort key排序
3.按排序后的顺序读取数据,因为sort_buffer_size中包含了所须要的字段,所以不须要再回表了,能够直接返回结果给客户端。内存
很明显,这种改进的方法对sort_buffer_size的需求也大大增长,因此为了防止性能降低,mysql增长了一个参数max_length_for_sort_data
当第一步中除了sort key之外的字段内容大于max_length_for_sort_data这个参数时,mysql将采用第一种排序算法。get
该参数默认为1024个字节,而在咱们的离线消息中内容较大,因此mysql就采用了第一种排序算法,结果每次都要回表,因此性能不好。
将max_length_for_sort_data该参数调大,性能获得了很大的提升。it
人人都说mysql简单,其实在DB层面没有简单的事情,任何一个细小的东西里面都大有文章可讲啊。
另外http://forge.mysql.com/wiki 这个wiki上面的内容很不错,强烈推荐一下。原理