排序

“排序”这个动作,可能在内存中完成,也可能需要使用外部排序,这取决于排序所需的内存和参数 sort_buffer_size。sort_buffer_size,就是 MySQL 为排序开辟的内存(sort_buffer)的大小。如果要排序的数据量小于 sort_buffer_size,排序就在内存中完成。但如果排序数据量太大,内存放不下,则不得不利用磁盘临时文件辅助排序。

通过查看 OPTIMIZER_TRACE 的结果来确认的,你可以从 number_of_tmp_files 中看到是否使用了临时文件。

 number_of_tmp_files 表示的是,排序过程中使用的临时文件数。你一定奇怪,为什么需要 12 个文件?内存放不下时,就需要使用外部排序,外部排序一般使用归并排序算法。可以这么简单理解,MySQL 将需要排序的数据分成 12 份,每一份单独排序后存在这些临时文件中。然后把这 12 个有序文件再合并成一个有序的大文件。如果 sort_buffer_size 超过了需要排序的数据量的大小,number_of_tmp_files 就是 0,表示排序可以直接在内存中完成。否则就需要放在临时文件中排序。sort_buffer_size 越小,需要分成的份数越多,number_of_tmp_files 的值就越大。

当ORDER BY的条件与联合索引排序规则保持一致时,直接查询即可,无需排序,因为数据在插入时就已经按索引顺序拍好了。

什么情况下ORDER BY 索引排序会失效呢?

以联合索引index(name,age)为例,无法利用索引排序的情况:

order by age,name(字段顺序不一致),因为索引是按照name,age排序的,没有按age,name排序的规则,所以需要重新排序。

order by name desc,age asc(字段排序方式不同步,desc和asc混着来) ,维护索引的排序规则未name ASC,age ASC来排序的,如果你使用一个不一致的排序方式,与索引排序方式不匹配时,需要重新排序。

即使索引的排序方式是顺序排序的,但当查询时都为倒序时也能使用索引的排序,为什么?

因为倒序为顺序的取反,所以只需得到顺序的结果,取反即可。

存在where条件时

但如index(a,b,c) where a = 1 order by b,c也是可以利用索引排序的 为什么? where是返回结果前的过滤,当where过滤完后得到的结果其实是按照了3个字段排序后的结果,此时order by 在进行排序时,就是已经拍好序的结果了。

但当where中使用了范围查询,order by将不能使用索引排序。

posted on 2024-06-24 22:19  zhengbiyu  阅读(25)  评论(0)    收藏  举报