sql优化步骤
一.查看sql执行频率
show [session|global] status命令可以提供服务器状态信息
session;当前链接的统计结果
global:自数据库上次启动自今的统计结果
如果不写默认为session
show status like 'Com_______';
//七个下划线
show status like 'Com_insert';
查询Innodb引擎表执行频次
show global status like 'Innodb_rows_%';
二. 定位低效率执行sql
1.慢查询日志,通过慢查询日志定位效率地的sql语句。mysqld写一个包含所有执行时间超过long_query_time秒的sql语句执行文件。
2.show processlist:慢查询日志查询结束后才有记录。所以在应用反应执行效率出现问题时查询慢查询日志并不能定位问题。show processlist命令可以查看当前mysql在进行的线程,包括线程的状态,是否锁表等,可以实时查看sql的执行情况,同时对锁表操作进行优化。
explain分析执行计划
explain select * from table where id=1;
explain select * from table where title='sanxing';
id:代表表的执行循序,相同,表加载重上到下;不同,id越大,优先级越高,越先被执行。
select_type:
show profile分析sql
查询mysql是否支持profile
set profiling=1;开启profile
查询是否开启
show profiles;
查询每条sql语句执行耗时;
show profiles for query 4;
查询sql语句的每一步执行时间
trace分析优化器执行计划
三.大批量出入数据优化
load data local infile '/root/sql1.log' into table 'table1' fields terminated by ',' lines terminated by '\n';
1.导入数据要维护索引,Innodb索引结构为B+树,有序数据能够提高批量导入数据的效率。
2.关闭唯一性校验:
set unique_checks=0;
3.手动提交事务
set autocommit=0;
四.sql优化
insert优化
1.优化前:
insert into tb values(3,'tom');
insert into tb values(1,'tom');
insert into tb values(2,'tom');
优化后:
insert into tb values(1,'tom'),(2,'tom'),(3,'tom');
2.在事务中进行数据插入,事务改为手动事务
start transaction;
insert into tb values(3,'tom');
insert into tb values(1,'tom');
insert into tb values(2,'tom');
commit;
3.有序插入数据,按主键顺序插入:
insert into tb values(1,'tom');
insert into tb values(2,'tom');
insert into tb values(3,'tom');
orderby优化
1.通过extra:Using filesort,文件系统排序,效率低
explain select *from emp order by age desc;
2.Using index 排序,通过有序的索引顺序返回结果,要求排序内容要覆盖索引,order by要和索引的顺序相同,并且order by的顺序要么是升序要么是降序,否则肯定需要额外的操作
explain select id, age from emp order by age;
group by优化
分组实在排序的基础上进行的,分组之前可以order by null
explain select age,count(*) from emp group by age order by null;
嵌套查询优化
避免子查询,尽量使用多表联查。
explain select *from user where id in(selcet id from role);
优化后:
explain select * from user,role where user.id=role.id;
or的优化
使用or不走索引
select * from user name='fang' or age=15;
使用union 替换or
limit优化
1.在索引上完成排序分页操作,最后根据主键关联回原表查询所需要的其他内容。
select * from emp e,(select id from emp order by id limit 200000,10 ) a where e.id=a.id;
2.该方案使用于主键自增的表,可以把limit查询换成某个位置的查询。
select * from emp where id>200000 limit 10;