如何通过内部实现mysql排序?

时间:2011-08-05 10:37:40

标签: mysql performance

Mysql如何在内部实施订购?将按多个列排序涉及按约束顺序指定的每个列多次扫描数据集一次?

2 个答案:

答案 0 :(得分:1)

以下是描述:

http://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html

除非您有行外列(BLOBTEXT)或您的SELECT列表太大,否则会使用此算法:

  
      
  • 读取与WHERE子句匹配的行。

  •   
  • 对于每一行,记录一个由排序键值和行位置组成的值元组,以及查询所需的列。

  •   
  • 按排序键值

  • 对元组进行排序   
  • 按排序顺序检索行,但直接从已排序的元组中读取所需的列,而不是第二次访问该表。

  •   

按多列排序不需要扫描数据集两次,因为排序所需的所有数据都可以在一次读取中获取。

请注意,MySQL可以完全避免订单,只需按顺序读取值,如果您的索引最左边的部分符合ORDER BY条件。

答案 1 :(得分:0)

MySQL 很精明。它的排序算法取决于几个因素 -

Available Indexes
Expected size of result
MySQL version

MySQL 有两种方法来生成排序/有序的数据流。

1.索引的巧妙使用

首先,MySQL 优化器分析查询并确定它是否可以利用可用的排序索引。如果是,它自然会按索引顺序返回记录。 (NDB 引擎除外,它需要在从所有存储节点获取数据后执行归并排序)

交给 MySQL 优化器,他很聪明地判断索引访问方法是否比其他访问方法便宜。

在这里看到的东西真的很有趣

  • 即使 ORDER BY 与索引不完全匹配,也可以使用索引,只要 ORDER BY 中的其他列是常量
  • 有时,如果优化器发现索引与扫描表相比开销很大,则它可能不会使用索引。

2.文件排序算法

如果索引不能用于满足 ORDER BY 子句,MySQL 使用文件排序算法。这是一个非常有趣的算法。简而言之,它的工作原理是

  • 它扫描整个表并找到与 WHERE 条件匹配的行

  • 它维护一个缓冲区并存储其中每一行的几个值(排序键值、行指针和查询中所需的列)。这个chunk的大小是系统变量sort_buffer_size。

  • 当缓冲区已满时,它会根据排序键对其进行快速排序,并将其安全地存储到磁盘上的临时文件中,并记住指向它的指针

  • 它将对数据块重复相同的步骤,直到没有更多的行

  • 现在,它有几个已排序的块

  • 最后,它对所有已排序的块应用归并排序并将其放入一个结果文件中

  • 最后,它将从排序结果文件中获取行

如果预期的结果适合一个块,则数据永远不会到达磁盘,而是保留在 RAM 中。

详细信息 - https://blog.pankajtanwar.in/what-is-the-sorting-algorithm-behind-order-by-query-in-mysql