1.优化sql语句一般步骤:
1)show status like 'Com_%'; 显示当前session中所有统计参数的值,我们关心的是增删改查各占比例,或者Innodb引擎的表的操作累计,还有慢查询次数Slow_queries
2) show processlist查看mysql正在进行的线程,包括线程的状态 是否锁表等,也可以通过慢查询日志定位那些效率很低的SQL语句,日志文件路径可查看配置;
3)通过explain分析效率比较低的SQL的执行计划,explain结果有几项,我们关心的主要是
select_type,包括simple,primary,union,subquery等
type,包括 all, index,range,ref,eq_ref,const/system,null
possible_keys:可能用到的索引
key:标示实际用到的索引
rows:扫描行的数量
extra:执行情况的说明和描述
4)通过show profile分析SQL 查看sql语句执行过程中线程的每个状态和消耗的时间
5)通过trace分析优化器如何选择执行计划
2.针对性优化措施
1)建立索引 常见的是B Tree索引(平衡树)
2)存在索引但不能使用的场景 如以%开头的like查询,数据类型出现隐式转换的时候,复合索引在查询条件不包含最左边部分的时候,or前的条件列有索引而后面的没有索引的时候等等,前缀索引在order by 和groupby操作的时候无法使用
3)optimize语句压缩碎片
4)大批量导入数据的场景:考虑将导入的数据按照主键的顺序排列;在导入数据前执行set unique_check=0关闭唯一性检查,在导入完成后再置为1;如果是自动提交的方式,set autocommit=0,关闭自动提交,导入完成后再置为1
5)优化insert语句
批量导入的时候采用多个值表的方式,缩减数据库连接关闭等开销;采用insert delayed语句,即把数据放到内存队列,放弃实时写磁盘;将索引文件和数据文件放到不同的磁盘;通过增加bulk_insert_buffer_size变量提高速度(MyISAM);load data infile 比insert快很多
6)优化order by语句
mysql有两种排序方式,1.通过有序索引顺序排序 2.通过对返回数据进行排序,即filesort排序内存排序
尽量减少额外的排序,通过索引值返回有序数据,where和order by使用相同的索引,并且order by的顺序和索引顺序相同
对于filesort排序,通过增大sort_buffer_size使得排序尽量再内存中完成,而不是通过临时表完成,另外尽量只使用必要的字段,而不是select *
7)优化group by语句
通过指定order by null禁止排序提升性能,不需要filesort
8)优化嵌套查询 通过join替换子查询提升效率
9)优化分页查询 比如limit 10000,200,此时mysql会排序出前10020条数据后返回10001到10020条记录,非常影响效率。
在索引上完成排序分页的操作,最后根据主键关联回原表查询所需要的其他列内容 for example:select a.film_id,a.description from film a inner join(select film_id from film order by title limit 50,20) b on a.film_id=b.film_id
把limit转化为id的查询 for example: select * from film where film_id<10020 order by film_id desc limit 20,前提是id无重复值且有索引
10)group by with roll up 统计聚合各组信息,还能检索出本组类的整体聚合信息,在汇总表单的时候很实用