MySQL调优笔记

MySQL调优笔记

代码层面:

减少对数据库访问的请求

减少无用数据的查询请求

MySQL Query的优化

Query语句的优化思路和原则主要提现在以下几个方面:

  1. 优化更需要优化的Query;

  2. 定位优化对象的性能瓶颈;

  3. 明确的优化目标;

  4. 从Explain入手;

  5. 多使用profile

  6. 永远用小结果集驱动大的结果集;

  7. 尽可能在索引中完成排序;

  8. 只取出自己需要的Columns;

  9. 仅仅使用最有效的过滤条件;

  10. 10.尽可能避免复杂的Join和子查询;

  11. where和on过滤条件加索引;

ORDER BY, GROUP BY和DISTINCT优化

1)ORDER BY的实现与优化

优化Query语句中的ORDER BY的时候,尽可能利用已有的索引来避免实际的排序计算,可以很大幅度的提升ORDER BY操作的性能。

优化排序:

1.加大max_length_for_sort_data参数的设置;

2.去掉不必要的返回字段;

3.增大sort_buffer_size参数设置;

2)GROUP BY的实现与优化

由于GROUP BY实际上也同样需要进行排序操作,而且与ORDER BY相比,GROUP BY主要只是多了排序之后的分组操作。当然,如果在分组的时候还使用了其他的一些聚合函数,那么还需要一些聚合函数的计算。所以,在GROUP BY的实现过程中,与ORDER BY一样也可以利用到索引。

3)DISTINCT的实现与优化

DISTINCT实际上和GROUP BY的操作非常相似,只不过是在GROUP BY之后的每组中只取出一条记录而已。所以,DISTINCT的实现和GROUP BY的实现也基本差不多,没有太大的区别。同样可以通过松散索引扫描或者是紧凑索引扫描来实现,当然,在无法仅仅使用索引即能完成DISTINCT的时候,MySQL只能通过临时表来完成。但是,和GROUP BY有一点差别的是,DISTINCT并不需要进行排序。也就是说,在仅仅只是DISTINCT操作的Query如果无法仅仅利用索引完成操作的时候,MySQL会利用临时表来做一次数据的“缓存”,但是不会对临时表中的数据进行filesort操作。

SQL语句的优化

1. 尽量避免使用子查询

img

2. 避免函数索引

img

3. 用IN来替换OR

img

MySQL对IN做了优化,即将IN中的常量全部存储在一个数组里面,而且这个数组是排好序的,数值较多时产生的消耗也较大。

4. LIKE前缀%、双%号、下划线查询非索引列或*无法使用到索引,如果查询的是索引列则可以

5. 读取适当的记录LIMIT M,N,而不要读多余的记录

select id,name 
from table_name limit 866613, 20

使用上述sql语句做分页的时候,可能有人会发现,随着表数据量的增加,直接使用limit分页查询会越来越慢。

优化的方法如下:可以取前一页的最大行数的id,然后根据这个最大的id来限制下一页的起点。

select id,name from table_name 
where id> 866612 limit 20

6. 避免数据类型不一致

7. 分组统计可以禁止排序sort,总和查询可以禁止排重用union all

union和union all的差异主要是前者需要将结果集合并后再进行唯一性过滤操作,这就会涉及到排序,增加大量的CPU运算,加大资源消耗及延迟。当然,union all的前提条件是两个结果集没有重复数据。所以一般是我们明确知道不会出现重复数据的时候才建议使用 union all 提高速度。

另外,如果排序字段没有用到索引,就尽量少排序;

8、避免随机取记录

img

9、禁止不必要的ORDER BY排序

img

10、批量INSERT插入

img

11、不要使用NOT等负向查询条件

你可以想象一下,对于一棵B+树,根节点是40,如果你的条件是等于20,就去左面查,你的条件等于50,就去右面查,但是你的条件是不等于66,索引应该咋办?还不是遍历一遍才知道。

12、尽量不用select *

SELECT *增加很多不必要的消耗(cpu、io、内存、网络带宽);增加了使用覆盖索引的可能性;当表结构发生改变时,前者也需要经常更新。所以要求直接在select后面接上字段名。

13、区分in和exists

select * from 表A 
where id in (select id from 表B)

上面sql语句相当于

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

区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询。所以IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。

14、优化Group By语句

如果对group by语句的结果没有排序要求,要在语句后面加 order by null(group 默认会去排序);

尽量让group by过程用上表的索引,确认方法是explain结果里没有Using temporary 和 Using filesort;

如果group by需要统计的数据量不大,尽量只使用内存临时表;也可以通过适当调大tmp_table_size参数,来避免用到磁盘临时表;

如果数据量实在太大,使用SQL_BIG_RESULT这个提示,来告诉优化器直接使用排序算法(直接用磁盘临时表)得到group by的结果。

你可能感兴趣的:(数据库)