MySQL order by的不同排序规则
Posted 爱叨叨的程序狗
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL order by的不同排序规则相关的知识,希望对你有一定的参考价值。
explain语句执行的结果中,Extra项中含有
Using filesort
表示需要排序,mysql
会给每个线程分配一块内存用于排序,称为sort_buffer。
全字段排序
全字段排序在内存中进行,不涉及磁盘IO、不需要回表操作,但数据量受内存大小影响,有局限性。
语句执行流程:
- 初始化sort_buffer,将需要查询的字段放入sort_buffer。
- 逐行或从索引中找到满足where条件的主键id。
- 将主键id索引取出整行,取查询出的字段值放入sort_buffer。
- 取下一个满足where条件的主键id。
- 重复步骤3、4,直到不满足where条件。
- 对sort_buffer中的数据按order by条件快速排序。
- 按照排序结果取数据返回。
rowid排序
rowid排序涉及磁盘IO,需要一次回表操作,不受内存大小限制。
当排序的字段较多时,内存可放下的行数很少,需要分成很多个临时文件,排序性能很差,即MySQL认为排序的单行长度太大会使用rowid排序。
语句执行流程:
- 初始化sort_buffer,将需要查询的字段放入sort_buffer。
- 逐行或从索引中找到满足where条件的主键id。
- 到主键id索引中取出整行,将查询的字段数据放入sort_buffer中。
- 取出下一个记录的主键id。
- 重复步骤3、4直到不满足where条件为止。
- 对sort_buffer中的数据按order by的条件进行排序。
- 遍历排序结果,取数据返回。
控制用于排序的行数据的长度,单行长度超过该值,MySQL更换排序算法 SET max_length_for_sort_data = 16;
使用索引排序
语句执行流程:
- 从索引找到第一个满足where条件的主键id
- 到主键id索引取出整行,找出需要返回的字段,作为结果集直接返回
- 从索引取下一个记录主键的id
- 重复步骤2、3,直到不满足where条件时循环结束。
当索引上的字段信息满足查询的结果集时(即覆盖索引),则不需要再回到主键索引上取数据。步骤2就变成了从索引上取出数据,作为结果集直接返回,节省一步回表操作。
使用覆盖索引时,explain
语句的Extra
字段会多了个"Using index",表示使用索引覆盖。
MySQL的一个设计思想:如果内存够,就要多利用内存,尽量减少磁盘访问。
以上是关于MySQL order by的不同排序规则的主要内容,如果未能解决你的问题,请参考以下文章
Mysql Order By 字符串排序,mysql 字符串order by
Mysql(15)—Order By排序的底层原理与filesort排序