【发布时间】:2011-08-05 10:37:39
【问题描述】:
Mysql order by 内部是如何实现的?按多列排序会涉及对按约束顺序指定的每一列多次扫描数据集吗?
【问题讨论】:
-
“视情况而定。”存在哪些索引?
标签: mysql performance
Mysql order by 内部是如何实现的?按多列排序会涉及对按约束顺序指定的每一列多次扫描数据集吗?
【问题讨论】:
标签: mysql performance
这里是描述:
http://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html
除非您有行外列(BLOB 或 TEXT)或您的 SELECT 列表太大,否则使用此算法:
读取与
WHERE子句匹配的行。对于每一行,记录一个由排序键值和行位置组成的值元组,以及查询所需的列。
按排序键值对元组进行排序
按排序顺序检索行,但直接从已排序的元组中读取所需的列,而不是再次访问表。
按多列排序不需要两次扫描数据集,因为一次读取即可获取排序所需的所有数据。
请注意,MySQL 可以完全避免顺序,只需按顺序读取值,前提是您的索引最左侧部分与您的 ORDER BY 条件匹配。
【讨论】:
MySQL 是精明的。它的排序算法取决于几个因素 -
Available Indexes
Expected size of result
MySQL version
MySQL 有两种方法来生成排序/有序的数据流。
首先,MySQL 优化器分析查询并确定它是否可以利用可用的排序索引。如果是,它自然会按索引顺序返回记录。 (NDB 引擎例外,它需要在从所有存储节点获取数据后执行归并排序)
交给 MySQL 优化器,他们聪明地判断索引访问方法是否比其他访问方法便宜。
在这里看到真的很有趣
如果不能使用索引来满足 ORDER BY 子句,MySQL 会使用文件排序算法。这是一个非常有趣的算法。简而言之,它就像
它扫描表并找到与 WHERE 条件匹配的行
它维护一个缓冲区并存储其中每一行的几个值(排序键值、行指针和查询中所需的列)。这个块的大小是系统变量sort_buffer_size。
当缓冲区已满时,它会根据排序键对其进行快速排序,并将其安全地存储到磁盘上的临时文件中并记住指向它的指针
它将对数据块重复相同的步骤,直到没有更多行了
现在,它有几个已排序的块
最后,它对所有已排序的块应用合并排序并将其放入一个结果文件中
最后,它会从排序后的结果文件中取出行
如果预期结果适合一个块,则数据永远不会到达磁盘,而是保留在 RAM 中。
了解详细信息 - https://www.pankajtanwar.in/blog/what-is-the-sorting-algorithm-behind-order-by-query-in-mysql
【讨论】: