您的位置:首页 > 数据库 > MySQL

MySQL Order by 、Group by 、Distinct的优化

2012-02-02 16:28 357 查看
一、Order by 的实现与优化:

在MySQL中,Order by的实现有两种,一是通过有序的索引直接取得有序的数据直接返回客户端;二是通过MySQL的排序算法进行排序后在将排序后的数据返回到客户端。

经实践证明利用索引实现数据排序的方法是MySQL 中实现结果集排序的最佳做法,可以完全避免因为排序计算所带来的资源消耗。所以,在我们优化Query 语句中的ORDER BY 的时候,尽可能利用已有的索引来避免实际的排序计算,可以很大幅度的提升ORDER BY 操作的性能 。

对于采取排序算法,MySQL有两种方式能够实现

1. 取出满足过滤条件的用于排序条件的字段以及可以直接定位到行数据的行指针信息,在SortBuffer 中进行实际的排序操作,然后利用排好序之后的数据根据行指针信息返回表中取得客户端请求的其他字段的数据,再返回给客户端;

2. 根据过滤条件一次取出排序字段以及客户端请求的所有其他字段的数据,并将不需要排序的字段存放在一块内存区域中,然后在Sort Buffer 中将排序字段和行指针信息进行排序,最后再利用排序后的行指针与存放在内存区域中和其他字段一起的行指针信息进行匹配合并结果集,再按照顺序返回给客户端。

这两种方式略有不同,能够看出来第二种方式优于第一种方式,第二种方式是典型的以内存为代价换取效率的提升。

二、Group by的实现与优化

由于GROUP BY 实际上也同样需要进行排序操作,而且与ORDER BY 相比,GROUP BY 主要只是多了排序之后的分组操作。当然,如果在分组的时候还使用了其他的一些聚合函数,那么还需要一些聚合函数的计算。所以,在GROUP BY 的实现过程中,与ORDER BY 一样也可以利用到索引。

在MySQL 中,GROUP BY 的实现同样有多种(三种)方式,其中有两种方式会利用现有的索引信息来完成GROUP BY,另外一种为完全无法使用索引的场景下使用。下面我们分别针对这三种实现方式做一个分析。

1. 使用松散(Loose)索引扫描实现GROUP BY

2. 使用紧凑(Tight)索引扫描实现GROUP BY

3. 使用临时表实现GROUP BY

三、Distinct的实现与优化

Distinct实际上和Group by 的操作非常相似,只不过是在Group by之后的每组中只取出一条记录而已。所以,Distinct的实现和Group by的实现也基本差不多,没有太大的区别。同样可以通过松散索引扫描或者是紧凑索引扫描来实现,当然,在无法仅仅使用索引即能完成Distinct的时候,MySQL只能通过临时表来完成。但是,和Group by有一点差别的是,Distinct并不需要进行排序。也就是说,在仅仅只是Distinct操作的Query 如果无法仅仅利用索引完成操作的时候,MySQL
会利用临时表来做一次数据的“缓”,但是不会对临时表中的数据进行filesort 操作。当然,如果我们在进行Distinct的时候还使用了Group by并进行了分组,并使用了类似于max之类的聚合函数操作,就无法避免filesort 了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: