MySQL 查询优化、【order by】及【group by】关键字优化

优化原则:小表驱动大表,即小的数据集驱动大的数据集

原理

select * from A where id in (select id from B)等价于

for select id from B {

for select * from A where A.id=B.id
}

当B表的数据集必须小于A表的数据集时,用in优于exists

select * from A where exists (select 1 from B where B.id=A.id)

等价于

for select * from A

for select * from B where B.id=A.id

当A表的数据集小于B表的数据集时,用exists优于in

order by关键字优化

order by字句尽量使用index方式排序,避免使用fileSort方式排序。

MySQL支持两种方式的排序,fileSort和index,index效率高。它指MySQL扫描索引本身完成排序。fileSort方法效率较低。

order by满足如下两种情况,会使用index方式排序

  • order by 语句使用索引最左前列
  • 使用where字句与order by子句条件列组合满足索引最左前列

尽可能在索引列上完成排序操作,遵照索引的最佳左前缀

fileSort排序原理

如果不在索引列上排序,fileSort有两种算法:双路排序和单路排序。

双路排序:MySQL4.1之前是使用双路排序,字面意思是两次扫描磁盘,最终得到数据。读取行指针和order by列,对他们进行排序,然后扫描已经排序好的列表,按照列表中的值重新从列表中读取对应的数据传输。

简单的说就是从磁盘取排序字段,在buffer进行排序,再从磁盘取其他字段。

单路排序:从磁盘读取查询需要的所有列,按照order by在buffer对它们进行排序,然后扫描排序后的列表进行输出,它的效率更快一些,避免了第二次读取数据,并且把随机IO变成顺序IO,但是它会使用更多的空间,因为它把每一行都保存在内存中了。

单路排序效率是比双路排序好,但是也有问题:

在sort_buffer中,单路排序比双路排序要多占用很多空间,因为单路排序是把所有字段都取出,所以有可能取出的数据总大小超出了sort_buffer的容量,导致每次只能取sort_buffer容量大小的数据,进行排序(创建tmp文件,多路合并),排完再取再排,从而会产生多次IO。

提高order by速度的方式

order by时select * 是一个大忌,只查询需要的字段,这点非常重要。在这里影响的是

  • 当查询的字段大小之和小于max_length_for_sort_data而且排序字段不是TEXT/BLOB类型时,会使用改进后的单路排序算法,否则使用多路排序算法

  • 两种算法的数据都有可能超过sort_buffer的容量,超过之后会创建tmp文件进行合并排序,导致多次IO。所以要提高sort_buffer_size。

  • 尝试提高sort_buffer_size

    不管哪种算法,提高这个参数都会提高效率。当然,要根据系统的能力去提高,因为这个参数是针对每个进程的。

order by 案例总结
使用索引进行排序的例子

加入一个表索引为 Key a_b_c(a,b,c)

order_by 能使用索引最左前缀

  • order by a
  • order by a,b
  • order by a,b,c
  • order by a desc,b desc,c desc

如果where使用索引的最左前缀定位为常量即一个确定的列值,则order by能使用索引

  • where a=const order by b,c
  • where a=const and b=const order by c
  • where a=const and b>const order by b
不能使用索引进行排序
  • order by a asc,b desc,c desc 排序不一致
  • where d=const order by b,c 不符合最左前缀规则
  • where a=const order by c 丢失b索引
  • where a=const order by a,d d不是索引的一部分
  • where a in (…) order by b,c
总结

因此 也就是说order by排序列要符合最左前缀规则或者order by排序列和where条件列 能够构成最左前缀规则也行。

group by关键字优化

group by实质是先排序后进行分组,遵照索引键的最佳左前缀,因此跟order by的优化很类似

发布了116 篇原创文章 · 获赞 23 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/zyxwvuuvwxyz/article/details/104596761
今日推荐