mysql order by排序深入理解



mysql 排序篇

 mysql 排序,如果从比较深入的角度来讨论这个命题,这一节完全可以出一本书。在这里我们只做简单介绍。

 mysql排序,这个动作会出现在两个两个地方,一个是内存,另一个是磁盘文件。由关键字order by 驱动。具体的排序条件根据结果集的字段决定。
 
 1 mysql 排序的算法
   mysql 的排序算法分为两种,一种是单路排序,一种是双路排序。
   
   双路排序: 按照sql指定的条件将符合的数据从磁盘中读取出来,把每一条数据参与排序的列以及这一行数据在磁盘中的位置(row point 又叫指针信息)
   丢给缓冲区,就是sort buffer. 在缓冲区中完成排序,之后将排序结果丢给随机读取缓冲区(read_rnd_buffer),随机读取缓冲区根据指针信息再到磁盘中读取该行数据的
   其他信息,之后再将合并结果返回给客户端。
   很明显 这种排序方法产生了两次IO操作。
   
   单路排序: 按照sql指定的条件将符合的数据从磁盘中全部读取出来,之后丢给缓冲区sort buffer ,缓冲区根据用户指定的排序条件完成排序,将结果返回给客户端。
   这种排序方式是在mysql 4.1之后出现的,选择单路排序需要一定条件。
   
   相比之下,单路排序比双路排序确实减少了IO次数,降低了磁盘开销,但是这里必须提出,减少IO操作的代价是增加了内存消耗。这是典型的用空间换时间的
   例子。
   
   我们如何让mysql使用单路排序呢?
   1 查询语句所取出的字段类型大小总和要小于 max_length_for_sort_data。
   2 排序字段中不包含text和blob类型。
   
 2 order by 的实现与优化
   还是那句话,良好的性能多取决于良好的设计,尤其是schema的早期设计。不要寄希望于后期的所谓的优化或者重构,那会让你痛苦。
   schema设计,尽可能把频繁访问的属性和冷属性分离,尽可能把小属性和大属性存放在不同的表里。去除不需要的业务设计,这会增加服务器负担。
   
   在设计sql语句的时候,你需要小心仔细,必须想象你的sql处理的是较大数据规模的情况,明确知道应用程序和mysql各自的优劣,比如mysql擅长表之间的join操作,而且这已经被
   mysql的开发者们优化的非常好,那么你就让mysql处理表之间的join,应用程序对于一些复杂计算和逻辑关系的处理表现的轻松自如,那么你就应该让mysql避免这一块。
   mysql忌讳大范围的磁盘IO,或者频度非常高的IO操作,那么排序就尽可能的利用索引,完善的索引设计也是高性能的保证。排序的过程中尽可能使用索引字段作为order by的条件。
   
   明白小结果集驱动大结果集的道理。这一点很重要。select 一定要去除不必要返回的数据,忌讳select *,因为你不需要,如果不得不返回你这次查询根本不需要的数据,那么请
   重新审查你的schema设计。不要盲目增大 max_length_for_sort_data 字段,这样会使Mysql 不得不将数据分成很多段然后进行排序。为了减少使用临时表,我们可以适当增大
   sort buffer size这个参数的大小,这样可以在排序过程中减少对数据的分段。

   请尊重知识,请尊重原创 更多资料参考请见  http://www.cezuwang.com/listFilm?page=1&areaId=906&filmTypeId=1

    原文作者:mysql
    原文地址: https://blog.csdn.net/annan211/article/details/84739437
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞