大部分查询中都要使用到order by。那么处理排序的方法有两种:一种是使用索引,另外一种则是查询时候使用Filesort处理。
1. 利用索引进行排:
利用有序索引进行排序,当 Query ORDER BY 条件和 Query 的执行计划中所利用的 Index 的索引键完全一致,且索引访问方式为 rang、 ref 或者 index 的时候,MySQL 可以利用索引顺序而直接取得已经排好序的数据。因为 MySQL 不需要进行实际的排序操作2. 利用内存或者磁盘排序算法:
1. single pass 1. two pass表结构:
5.7@3306>[employees]>show create table employees\G *************************** 1. row *************************** Table: employees Create Table: CREATE TABLE `employees` ( `emp_no` int(11) NOT NULL, `birth_date` date NOT NULL, `first_name` varchar(14) NOT NULL, `last_name` varchar(16) NOT NULL, `gender` enum('M','F') NOT NULL, `hire_date` date NOT NULL, PRIMARY KEY (`emp_no`) ) ENGINE=InnoDB DEFAULT CHARSET=utf81.使用索引进行排序:
5.7@3306>[employees]>desc select emp_no,first_name, last_name from employees order by emp_no desc limit 0,10; +----+-------------+-----------+------------+-------+---------------+---------+---------+------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+-------+---------------+---------+---------+------+------+----------+-------+ | 1 | SIMPLE | employees | NULL | index | NULL | PRIMARY | 4 | NULL | 10 | 100.00 | NULL | +----+-------------+-----------+------------+-------+---------------+---------+---------+------+------+----------+-------+2.使用single pass:
5.7@3306>[employees]>show status like '%sort%'; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | Sort_merge_passes | 0 | | Sort_range | 0 | | Sort_rows | 0 | | Sort_scan | 0 | +-------------------+-------+ 4 rows in set (0.00 sec) 5.7@3306>[employees]>select emp_no,first_name, last_name from employees order by first_name limit 100; 分析:将select的列,order 列放入到排序缓冲,进行排序处理,排序完成后,直接将排序缓冲中的内容返回。 5.7@3306>[employees]>show status like '%sort%'; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | Sort_merge_passes | 0 | | Sort_range | 0 | | Sort_rows | 100 | | Sort_scan | 1 | +-------------------+-------+ 4 rows in set (0.00 sec) 5.7@3306>[employees]>desc select emp_no,first_name, last_name from employees order by first_name limit 100; +----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+----------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+----------------+ | 1 | SIMPLE | employees | NULL | ALL | NULL | NULL | NULL | NULL | 299423 | 100.00 | Using filesort | +----+-------------+-----------+------------+------+---------------+------+---------+------+--------+----------+----------------+ 1 row in set, 1 warning (0.00 sec) 那么这样会造成什么问题:IO,网络等3.Two pass
5.7@3306>[employees]>show variables like "%max_length%"; +--------------------------+-------+ | Variable_name | Value | +--------------------------+-------+ | max_length_for_sort_data | 1024 | +--------------------------+-------+ 1 row in set (0.00 sec) 排序的值需要大于上面的值 5.7@3306>[employees]>show status like '%sort%'; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | Sort_merge_passes | 0 | | Sort_range | 0 | | Sort_rows | 0 | | Sort_scan | 0 | +-------------------+-------+ 4 rows in set (0.00 sec) 5.7@3306>[employees]> select count(1) from ( select * from employees order by first_name desc limit 100000000 ) a; +----------+ | count(1) | +----------+ | 300024 | +----------+ 1 row in set (0.87 sec) 5.7@3306>[employees]>show status like '%sort%'; +-------------------+--------+ | Variable_name | Value | +-------------------+--------+ | Sort_merge_passes | 25 | | Sort_range | 0 | | Sort_rows | 300024 | | Sort_scan | 1 | +-------------------+--------+ 4 rows in set (0.00 sec) 解释:Sort_merge_passes 超出sort buffer的值,将数据写入到了tmp file中优先选择第一种using index 的排序方式,在第一种方式无法满足的情况下,尽可能让 MySQL 选择使用第二种单路算法来进行排序。这样可以减少大量的随机IO操作,很大幅度地提高排序工作的效率。1、去掉不必要的字段2、加大max_length_for_sort_data 参数的设置3、增大sort buffer的设置
相关资源:敏捷开发V1.0.pptx