参考:  https://blog.csdn.net/wuseyukui/article/details/72627667

order by示例

示例数据:

Case 1

Case 2

Case 3

Case 4

结论:order by子句,尽量使用Index方式排序,在索引列上遵循索引的最佳左前缀原则。
复合(联合)索引形如 key (‘A1’,’A2’,’A3’ ),排序的思路一般是,先按照A1来排序,A1相同,然后按照A2排序,以此类推,这样对于(A1),(A1,A2), (A1,A2,A3)的索引都是有效的,但是对于(A2,A3)这样的索引就无效了。尽量避免因索引字段的缺失 或 索引字段顺序的不同 引起的FileSort排序。

order by 总结

FileSort排序算法

算法一:双路排序算法

只利用ORDERBY子句中包括的列对象进行排序(适用于有BLOB、TEXT类型的列对象参与的排序)

MySQL4.1之前的排序算法,完整实现过程如下:

1) 按索引键或全表扫描的方式,读取所有的元组,不匹配WHERE子句的元组被跳过;第一步需要从存储读入数据,引发I/O操作。

2) 对于每一行,在缓冲区中存储一对值(对值,包括排序关键字和元组指针)。缓冲区的大小是系统变量的sort_buffer_size设定的值。

3) 当缓冲区已满,运行快排算法(快速排序,qsort)对一个块中的数据进行排序,将结果存储在一个临时文件。保存一个指向排序后的块的指针(如果第二步所说的对值都能被缓冲区容纳,则不会创建临时文件)。

4) 重复上述步骤,直到所有的行已经被读取。

5) 执行一个多路归并操作(操作对象是第三步生成的每一个有序的块)汇集到“MERGEBUFF域”,然后存放到在第二个临时文件中。重复操作,直到第一个文件的所有块归并后存入到第二个文件;“MERGEBUFF域”是代码sql_sort.h中定义的宏,值为7。

6) 重复以下操作(第7步和第8步),直到留下少于“MERGEBUFF2域”标明的块数为止;“MERGEBUFF2域”是代码sql_sort.h中定义的宏,值为15。

7) 在最后一次多路归并操作中,把元组的指针(排序关键字的最后部分)写入到一个结果文件。

8) 在结果文件中,按照排列的顺序使用元组指针读取元组(为了优化这项操作,MySQL读入元组指针进入一个大的块,对块中元组指针进行排序而不是直接对数据排序,然后再用有序的元组指针获取元组到元组缓存,元组缓冲区的大小由read_rnd_buffer_size参数控制)。第8步需要从存储读入数据,引发I/O操作。

算法二:单路排序算法

除利用ORDERBY子句中包括的列对象外,还利用查询目标列中的所有列对象进行排序(适用于除BLOB、TEXT类型外的所有的其他类型的排序)

MySQL4.1之后出现的改进算法,减少一次I/O,需要增加缓冲区大小容纳更多信息。其具体实现过程如下:

1) 获取与WHERE子句匹配的元组。这一步需要从存储读入数据,引发I/O操作。

2) 对于每一个元组,记录排序键值、行的位置值、查询所需的列。这一步记录更多内容,需要更大缓存,内存存储一条元组的信息的长度比算法一的“对值”大许多,这可能引发排序速度问题(排序对象的长度变长,但是内存有限,所以就需把一次内存排序变为多次,进而影响排序的速度),为了控制这个问题,MySQL引入一个参数“max_length_for_sort_data”,如果这一步得到的元组长度大于这个值,则不使用算法二。需要MySQL的使用者特别注意的是,在排序中,如果存在“很高磁盘I/O和很低的CPU利用率”的现象,则需要考虑调整“max_length_for_sort_data”的大小以变更换排序算法。

3) 按照排序的键值,对元组(元组是第二步的结果)进行排序。

算法二直接从缓冲区中的排序的元组中获取有序的列信息等(查询的目的对象),而不是第二次访问该表读取所需的列。相比算法一减少一次I/O。

FileSort优化策略

当无法使用索引列排序时,为了提高Order By的速度,应该尝试一下优化:
1、避免使用 “select * ” 。查询的字段越多导致元组长度总合可能

超过max_length_for_sort_data的设置,导致无法使用单路排序算法,只能用双路排序算法。
超过sort_buffer_size的设置,超出后会创建tmp文件进行合并,导致多次IO
2、适当增大sort_buffer_size参数的设置

3、适当增大max_length_for_sort_data参数的设置

group by 示例

示例:

group by 总结

group by与order by的索引优化基本一样,group by实质是先排序后分组,也就是分组之前必排序,遵照索引的最佳左前缀原则可以大大提高group by的效率。

当无法使用索引列排序时,适当增大sort_buffer_size参数 + 适当增大max_length_for_sort_data参数可以提高filesort排序的效率。注意:可能会出现Using temporary,也就是说mysql在对查询结果排序时使用了临时表。

where高于having,能写在where限定条件中的就尽量写在where中。
---------------------
作者:走慢一点点
来源:CSDN
原文:https://blog.csdn.net/wuseyukui/article/details/72627667
版权声明:本文为博主原创文章,转载请附上博文链接!

MySQL高级 之 order by、group by 优化的更多相关文章

  1. MySQL高级知识(六)——索引优化

    前言:索引优化的目的主要是让索引不失效,本篇通过相关案例对索引优化进行讲解. 0.准备 创建经典的tb_emp表. DROP TABLE IF EXISTS `tb_emp`; CREATE TABL ...

  2. MySQL高级查询 之 与 Group By 一起使用的函数 和 关键字

    1 GROUP_CONCAT mysql> SELECT student_name, ->     GROUP_CONCAT(test_score) ->     FROM stud ...

  3. MySQL 高级 视图 事物 触发器 函数 索引优化

    视图 1.什么是视图 ​ 视图就是通过查询得到一张虚拟表,然后保存下来,下次直接使用即可 2.为什么要用视图 ​ 如果要频繁使用一张虚拟表,可以不用重复查询 3.如何用视图 create view t ...

  4. MySQL高级知识系列目录

    MySQL高级知识(一)——基础 MySQL高级知识(二)——Join查询 MySQL高级知识(三)——索引 MySQL高级知识(四)——Explain MySQL高级知识(五)——索引分析 MySQ ...

  5. MySQL高级知识(八)——ORDER BY优化

    前言:在使用order by时,经常出现Using filesort,因此对于此类sql语句需尽力优化,使其尽量使用Using index. 0.准备 #1.创建test表. drop table i ...

  6. Mysql查询优化汇总 order by优化例子,group by优化例子,limit优化例子,优化建议

    Mysql查询优化汇总 order by优化例子,group by优化例子,limit优化例子,优化建议 索引 索引是一种存储引擎快速查询记录的一种数据结构. 注意 MYSQL一次查询只能使用一个索引 ...

  7. MySQL高级学习笔记(四):索引优化分析

    文章目录 性能下降 SQL慢 执行时间长 等待时间长 查询语句写的烂 查询数据过多 关联了太多的表,太多join 没有利用到索引 单值 复合 服务器调优及各个参数设置(缓冲.线程数等)(不重要DBA的 ...

  8. 【MySQL 高级】索引优化分析

    MySQL高级 索引优化分析 SQL 的效率问题 出现性能下降,SQL 执行慢,执行时间长,等待时间长等情况,可能的原因有: 查询语句写的不好 索引失效 单值索引:在 user 表中给 name 属性 ...

  9. 「MySQL高级篇」explain分析SQL,索引失效&&常见优化场景

    大家好,我是melo,一名大三后台练习生 专栏回顾 索引的原理&&设计原则 欢迎关注本专栏:MySQL高级篇 本篇速览 在我们上一篇文章中,讲到了索引的原理&&设计原则 ...

随机推荐

  1. blockstack与Ethereum

    https://github.com/blockstack https://bihu.com/article/1260288 blockstack是用户登录的认证中心,类似java中的OAuth2进行 ...

  2. DDL/DML/DCL区别

    DDL DDL的概述 DDL(Data Definition Language 数据定义语言)用于操作对象和对象的属性,这种对象包括数据库本身,以及数据库对象,像:表.视图等等,DDL对这些对象和属性 ...

  3. Fix multiple GPUs fails in training Mask_RCNN

    Test with: Keras: 2.2.4Python: 3.6.9Tensorflow: 1.12.0 ================== Problem: Using code from h ...

  4. 一种SpaceClaim抽取流道的方法——利用缺失的面功能

    针对不干净的几何,内部存在诸多碎面小缝隙,采用此方法可能会有较好的效果,不过需要耐心. 测试几何需要SpaceClaim19.0以上软件可以打开,下载链接: https://pan.baidu.com ...

  5. CandyCrush 糖果传奇源码+素材+教程

    在这里你将深入学习C#语言和Unity开发游戏的技术.在游戏项目开发中深入学习并掌握Unity开发中的刚体,模型等等 共14讲,TS格式,大小395MB 共14讲,TS格式,大小395MB 扫码时备注 ...

  6. 防止同一IP多次请求攻击

    防止同一IP多次请求攻击 防止入侵者,通过死循环同一时间批量向服务器请求数据,导致服务器内存开销不断膨胀,最后直接瘫痪. 一. 新增一个spring的拦截器 , 拦截所有请求 <mvc:inte ...

  7. bootstrap Tab页切换

    <ul class="nav nav-tabs" id="otherInfoTab"> <li class="active" ...

  8. jQuery-webcam使用

    基本页面 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta ...

  9. 2019年计算机技术与软件专业技术资格(水平)考试安排v

    根据<关于2019年度专业技术人员资格考试计划及有关问题的通知>(人社厅发[2018]142号)要求,2019年度计算机技术与软件专业技术资格(水平)考试(以下简称计算机软件资格考试)安排 ...

  10. MySQL使用存储过程实现判断表中字段或者索引是否存在,如果不存在则创建

    使用存储过程可以保证数据库升级脚本可以重复执行而不会报错. CREATE TABLE `tb_user` ( `id` ) NOT NULL COMMENT '非自增id', `account` ) ...