Msyql优化

Msyql优化

一、 定位低效率执行SQL-慢查询日志

– 查看当前会话SQL执行类型的统计信息

show session status like 'com_______';

– 查看全局(自从上次MySQL服务器启动至今)执行类型的统计信息

show global status like 'com_______';

– 查看针对InnoDB引擎的统计

show status like 'Innodb_rows_%';

– 查看慢日志配置信息

show variables like '%slow_query_log%';

– 开启慢日志查询

set global slow_query_log = 1;  --  0表示关闭

– 查看慢日志记录SQL的最低阈值时间
– SQL的执行时间>=10秒,则算慢查询

show variables like '%long_query_time%';

– 例子
select sleep(10);

– 临时修改慢查询日志记录SQL的最低阈值时间

set globla long_query_time = 5; 

二、 查询SQL动态执行状态

– show proccesslist 查看客户端短连接服务器的线程执行状态信息

show processlist;

三、explain分析执行计划

explain select level,score_grade,
	round(count(score_grade)/total,3) ratio
from (select uid,level,score_grade,
	count(score_grade) over(partition by uid) total
from
(select uid,exam_id ,score ,level,
	case 
		when score >=0 and score<60 then '差'
		when score >=60 and score<75 then '中'
		when score >=75 and score<90 then '良'
		when score >=90 and score<=100 then '优'
		else null
	end score_grade
from exam_record
left join  user_info ui  
using(uid)
where score is not null) t1)t2
group by level,score_grade
order by level desc,ratio desc
;

在这里插入图片描述

Explain执行计划之ID

– id相同表示加载表的顺序是从上而下
– id不同,id值越大优先级越高,越先被执行

– Explain执行计划之select_type
– SIMPLE:没有子查询和union

– PRIMARY :主查询 子查询中的最外层查询

– SUBQUERY : 在select和where中包含子查询

– DERIVED : 在from中包含子查询,被标记为衍生表

– UNION : 若第二个select出现在UNION之后,则标记为UNOIN;若UNION包含在FROM子句的子查询中,外层selec 将被标记为:DERIVED

Explain执行计划之type

– all:全表扫描 最差的一种查询方式
– NULL:不访问任何表,直接返回结果
– system :查询系统表,直接从内存读取,不会从磁盘读取 5.7及以上版本不再显示system,直接显示all
– const: 命中主键或者唯一索引;被连接的部分是一个常量值
– eq_ref;左表有主键,而且左表的每一行和右表的每一行刚好匹配
– ref : 左表有普通索引,和右表配置是可能会匹配多行
– range:范围查询 where uid>3
– index : 把索引列的全部数据都扫描

Explain执行计划之其他指标字段

– using filesort: 说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取,成为“文件排序”,效率低。
– using temporay: 需要建立临时表(temporay table)来暂存中间结果,常见于order by 和group by ;效率低
– using index : SQL所需要返回的所有列数据均在一颗索引树上,避免访问表的数据行,效率不错。

四、show profile 分析SQL

– 查看当前MySQL是否支持profile

select @@have_profiling;

– 如果不支持,设置打开

set profiling = 1;

– 查看执行命令的时间

show profiles;

show profile for query 13;

– 查看cpu的耗费时间

show profile cpu for query 25;

五、 trace分析优化器执行计划

set optimize_trace = "enabled=on",end_markers_in_json=on;
set optimize_trace_max_mem_size=1000000;

– doc终端执行

select * from information_schema.OPTIMIZER_TRACE ot \G;

六、 索引优化

创建组合索引

create index idx_seller_name_sta_addr on table(name,staus,address);

七、避免索引失效

避免索引失效之全值匹配:

和索引字段全部成功匹配,无顺序

避免索引失效之最左前缀法则:

组合索引中的最左边的字段(name)存在,索引才生效;若跳跃某一个子段(name->address),只有最左列(name)索引生效;

避免索引失效之其他匹配原则:

1范围查询右边的列不能使用索引(address索引失效)
select * from table where name='小米科技' and status >'1' and adress='北京'
2不要索引列上进行运算操作(name索引失效)
select * from table where substring(name,2,3)='科技';
3字符串不加单引号,造成索引失效(status索引失效)
select * from table where name = '小米科技' and status= 1;
4尽量使用覆盖索引(只访问索引的查询(索引列完全包含查询列)),减少select *(从磁盘读取数据)
select name from table where name='小米科技';
5用or分隔开的条件,则涉及的索引都不会被用到
select name from table where name='小米科技' or status = '1';
6以%开头的Like模糊查询,索引失效 可以使用select name(索引列),弥补不足
select * from table where name like '%科技';
7如果MySQL评估使用索引比全表更慢,则不使用索引
8is null ,is not null 有时候有效,有时索引失效(谁的数据少谁有效)
select * from table where name is null; -- 有效
select * from table where name is not null ; -- 无效
9 in走索引,not in 不走索引,如果是主键索引或者唯一索引,都使用
10尽量使用组合索引(如果一个表有多个单列索引,即使where中都是用了这些索引列,则只有一个最优索引生效)

八、SQL优化

大批量插入数据

1.主键顺序插入
2.关闭唯一性校验:在导入数据之前,如果表中有唯一索引,在插入时会对每一个数据就行校验
set unique_checks=0;
set unique_checks=1;

1) 优化insert语句

1.减少客户端连接
insert into table values(1,'tom'),(2,'tom'),(3,'tom');
2.手动开启事务,在事务中进行数据插入
begin;
insert into table values(1,'tom');
insert into table values(2,'tom');
insert into table values(3,'tom');
commit;
3.有序插入

2)优化order by语句

1、两种排序方式 filesort/using index
create index idx_emp_age on emp(age,salary)

explain select * from emp order by age; -- using filesort
explain select age from emp order by age; -- using index
order by后面的多个排序字段要求尽量排序方式相同
explain select id,age from emp order by age,id;
order by后面的多个排序字段顺序尽量和组合索引字段顺序一致
explain select id,age from emp order by salary,age; -- using index;using filesort
2、fielsort优化

两次扫描算法;会有产生磁盘IO操作,效率低
一次扫描算法:效率高
扩大max_length_for_sort_data 和 sort_buffer_size 的值,会优先使用一次扫描

优化子查询

子查询可以被join替代(因为子查询需要在内存中创建临时表)

3)优化limit查询

1.在索引上完成排序分页操作,最后根据主键关联原表进行查询
select * 
from table a ,(select id from table order by id limit (90000,10)) b where a.id = b.id;
2.把limit查询转换成某个位置的查询,适用于主键自增的表
select * from table where id>90000 limit 10;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值