mysql中Order by 优化

最好做法:

利用索引避免排序,B+tree 索引本身的有序性,让mysql跳过排序过程。

排序方式

mysql排序模式1.-rowid排序(常规排序)

1.从表中获取满足where条件的记录

2.对于每条记录,将记录的主键及排序键(id、order_column)取出放入sort buffer(sort_buffer_size控制)

3.如果sort buffer能存放所有满足条件的(id、order_column),则进行排序;否则sort buffer 满后,排序并写到临时文件。 排序算法:快速排序算法

4.若排序中产生了临时文件,需要利用归并排序算法,从而保证记录有序

5.循环执行上述过程,直到所有满足条件的记录全部参与排序

6.扫描排好序的(id、order_column)对,并利用id去取select需要返回的其它字段

7.返回结果集

rowid排序特点:

1).看sort buffer是否能存放结果集里面的所有(id、order_column),如果不满足,就会产生临时文件
2)一次排序需要2次IO:
第二步中:把(id、order_column)扔到sort_buffer;
第六步中:通过id去获取需要返回的其它字段。由于返回结果是按照order_column排序的,所以id是乱序的,会存在随机io的问题。mysql内部针对这个情况做个优化:在用id取数据之前,会按照id排序并放到一个缓存里,这个缓存大小由read_rnd_buffer_size控制,接着再去取记录,从而把随机io转换成顺序IO

mysql排序模式2.-全字段排序(优化排序)

1.直接取出sql中需要的所有字段,放到sort buffer
2.由于sort buffer已经包含了查询需要的所有字段,因此在sort buffer中排序完成后可直接返回

全字段排序 VS rowid排序

1.优点:性能的提升,无需两次IO
2.缺点:一行数据占用的空间一般比rowid排序多;如果sort buffer比较小,容易导致临时文件

算法如何选择?

Max_length_for_sort_data(默认1024字节):当order by sql中出现字段总长度小于该值,使用全字段排序,否则使用rowid排序

mysql排序模式3.-打包字段排序

1.mysql 5.7引入
2.全字段模式的优化,与全字段排序工作原理一样,但是将字段紧密的排列在一起,而不是使用固定长度空间
例子:varchar(255) 存储“yes”,不打包:255字节;打包:2 + 3字节(2个字节保存长度,3个字节保存”yes”)

OPTIMIZER_TRACE使用

1.开启OPTIMIZER_TRACE功能,并设置要展示的数据条目数:

set optimizer_trace="enabled=on" ,end_markers_in_json=on;
set optimizer_trace_offset=-30,optimizer_trace_limit=30;

2.发送你想要分析的sql语句,例如:

select * from employees where first_name <'Bader' order by last_name;

3.分析查询结果

select * from `information_schema`.optimizer_trace where query like '%Bader%';

得到如下结果:在这里插入图片描述
分析trace结果:
在这里插入图片描述

Memory_available:可用内存,就是sort_buffer_size配置的值
Num_rows_found:有多少条数据参与排序,越小越好
Num_initial_chunks_spilled_to_disk:产生了几个临时文件,0表示完全基于内存排序
Sort_mode:packed_addition_fields代表打包排序;addition_fields 代表全字段排序

如何调优order by

1.利用索引,防止filesort的发生
2.如果发生了filesort,并且没办法避免,想办法优化filesort

调优方案:

1.调大sort_buffer_size,减少/避免临时文件、归并操作,怎么判定要调整这个值呢?

依据:
a)Optimizer trace中num_initial_chunks_spilled_to_disk的值,值大就可以调整
b)Sort_merge_passes变量的值,值越大,归并的次数就越大,就可以调整

2.调大read_rnd_buffer_size,让一次顺序IO返回的结果更多
3.设置合理的max_length_for_sort_data的值(慎重调整,不建议随意调整)
4.调小max_sort_length(排序时最多取多少字节)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿在京

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值