目的:1.避免慢查询形成页面没法加载mysql
2.因为数据库链接timeout产生5xx错误sql
3.因为阻塞形成数据没法提交数据库
慢查询分析日志:pt-query-digest分析前几个查询函数
优化当面入手:优化
硬件,系统配置,数据库表结构,sql及索引 效果:低到高 成本: 高到低操作系统
rpm -qal | grep mysql 查找mysql字段目录线程
ps -ef | grep mysql 查看线程号和目录unix
cat /etc/my.conf mysql配置文件日志
datadir是你数据文件的存放路径排序
basedir才是mysql软件的安装路径
explain --查询sql执行技术
key_len:使用的索引的长度,在不损失精确度状况下,长度越短越好
ref:显示索引的哪一列被使用,若是可能的话,是一个常数最好
type 显示链接使用什么类型,从好到差:const,eq_reg,ref,range,index,all
extra列须要注意的返回值
Using filesort: 查询须要优化,须要额外的步骤来发现如何对返回的行排序,使用文件排序
Using temporary: 查询须要优化 ,这里建立临时表进行存储结构,一般发生在不一样列集上的order by,而不是group by
备份
mysqldump --all-databases > all-databases.sql(将全部数据库备份到all-databases.sql文件,all-databases.sql是一个文本文件,文件名任取。)
count()和max()优化:
count(*)查询行数
count(1)查询不为null的行数
max(age)->age字段创建索引 count()同理
子查询优化:
改成链接join查询(注意1对多关系)
group by优化方式:
在子查询用group by过滤条件
例如:
优化前:explain select a.name,c.cnt from a inner join b using id group by b.id;
优化后:explain select a.name,c.cnt from a inner join(select id,count(*) from b group by id) as c using id;
limit优化方式:
limit经常使用分页处理,时常会伴随order by 从句使用,所以常常会形成filesort这样的I/O问题
步骤1:使用索引的列或者主键进行order by操做
步骤2:借助上一次返回的id,用id进行过滤,缺点:id自增且连续 --->避免数量亮大时扫描过多的记录
例如:select id from a where id >55 and id<=60 order by id limit 1,5;
如何选择合适的列创建索引?
1.在where,group by ,order by,on 从句中出现的列
2.索引字段越小越好
3.离散度大的列放在联合索引前面
例如:select * from payment where staff_id =2 and customer_id =584;
因为customer_id离散度更大,因此应该是(customer_id,staff_id);
如何判断列的离散度大小 ---> select count(distinct customer_id) from payment; -->599
select count(distinct staff_id) from payment; -->2
索引优化
过多的索引会影响写入,有时也会影响查询
冗余索引:多个索引的前缀列相同,或在联合索引中包含了主键的索引,下面key(name,id)就是一个冗余索引
create table test(
id int not null primay key,
name varchar(10) not null,
title varchar(50) not null,
key(name,id)
)engine=innodb
重复索引:相同的列以相同的顺序创建的同类型的索引。下面primary key和id列上的索引就是重复索引
create table test(
id int not null primay key,
name varchar(10) not null,
title varchar(50) not null,
unique(id)
)engine=innodb
使用pt-duplicate-key-checker -uroot -p'' -h127.0.0.1检查重复索引和冗余索引
选择的合适的数据类型
1.使用能够存下你的数据的最小数据类型
2.使用简单的数据类型,int要比varchar类型在mysql处理上简单
3.尽量使用not null定义字段
4.尽可能少用text类型,非用不可时最好考虑分表
使用int来存储日期时间,利用from_unixtime(),unix_timestamp()2个函数来进行转换
使用bigint来存ip地址,使用inet_aton(),inet_ntoa()2个函数来替换
表的垂直拆分,水平拆分
垂直拆分:将单表按照业务拆分多个表
水平拆分:单表分红多个相同的表,表1,表2,表3。。。。。
操做系统配置优化