王志广的个人分享

如何优化MYSQL

admin发表于2014-12-18  3,750次浏览 标签: 

优化MYSQL不单单只是查看程序,查看数据库,建立索引来优化,优化MYSQL是一个复杂的系统工程,就像看一个病人一样,不能服务器没有问题就去给他优化,也不能随便去优化,我们要先望闻问切了解MYSQL出了什么问题,然后根据实际情况去优化。特别注意的是一定要根据实际情况去优化。

 

第一步查看服务器状态
首先我们要建立一个脚本查看服务器MYSQL占用CPU和内存状态,查看是否是波动周期性问题,还是MYSQL占用一直很高,如果是有周期性,那分析是否是网站访问量高峰还是我们程序设置或者重新建立缓存引起的,如果是建立缓存和程序引起的,那我们要考虑的是把建立缓存时间分散,或者修改程序。

第二步查看MYSQL慢在哪里
查看是否是服务器参数问题,或者是缓存区线程问题,或者是MYSQL自己内部语句问题。分析MYSQL内部问题时候我们需要show processlist或者开启慢查询,查看问题出在那条sql语句上,然后针对这条sql语句去优化。

第三步MYSQL语句优化
所以分析慢在哪里,是等待时间长还是执行时间长,这时候我们需要用到explain分析语句
语法:explain sql语句;
列解释
id select的编号从1开始或者子查询编号
table 表名或者别名等
select_type select的类型分为simple(简单)primary(最外层的select)union(第二层在select之后使用了union)dependent union(语句中的第二个select依赖于外部子查询)subquery(子查询中的第一个select)dependent subquery(子查询中的第一个subquery依赖于外部的子查询)derived(派生表select)
type 连接类型由快到慢 null(不用再访问表或索引) const,system(系统表或就一条数据) eq_ref(从该表中会有一行记录被读取出来以和从前一个表中读取出来的记录做联合) ref range(只有在给定范围的记录才会被取出来,利用索引来取得一条记录) index(连接类型跟all一样不同的是它只扫描索引树) ALL(将对该表做全部扫描以和从前一个表中取得的记录作联合)
possible_keys 可能用到的索引
key 实际用到的索引
key_len 索引最大长度
ref 连接查询时,前表与后表的引用关系
rows 估计扫描了多少列
extra 显示了查询中mysql的附加信息 using index(适用索引) using where(适用条件) using temporary(使用到临时表) using filesort(排序与使用的索引的排序一致)

关联子查询分析 查看in型子查询实际效果(会扫描前面表的全部),exists子查询和join和group比较,from子查询减少返回行数和查看派生表用没有用索引

语句优化 min/max优化放到程序中,count优化(最好也放到程序中,统计全部时myisam有个表简介,count很快),关联表优化,group by优化,limit优化(limit 开始数越大越慢,需要扫描前面数据),union优化

变量优化 mysql变量运算这个放到程序中数度更快

避免用NULL

第四步优化SQL语句离不开索引的优化
首先我们选择索引类型是Btree还是hash,hash索引虽然理论寻址高效但是无法排序优化也只能满足”=”,”IN”和”<=>”查询,也不能避免表扫描,而且myisam和innodb不支持,所以我们一般用的是btree索引,如果你的业务逻辑满足hash索引条件而且数据量不多可以使用hsah。

然后我们在分析表的类型,myisam和innodb,myisam索引指向的是物理行而innodb指向的是对主键的引用,同时myisam非事务安全性,支持全文索引,也相对简单,快速,而且存储是以文件的方式存储。innodb支持事务,视图,安全,不支持全文索引,相对复杂,性能稍慢。相对来说数据少用myisam好,数据多用innodb稍微好些。

字段类型优先级 整型 > date,time > enum,char>varchar > blob

好索引方法:
建立索引时我们可以减少索引存储长度或者把字符串变为crc32int型
多列索引时我们要考虑列的区分度和列的适用频率,如果不频繁适用就减少索引列,还有如果列中内容区分度不是很大,也最好不要建立索引。
聚簇索引innodb的主索引文件上直接存放该行数据,称为聚簇索引,次索引指向对主键的引用,而myisam中,主索引和次索引,都指向物理行。优势: 根据主键查询条目比较少时,不用回行(数据就在主键节点下)、劣势: 如果碰到不规则数据插入时,造成频繁的页分裂.
索引覆盖是指如果查询的列恰好是索引的一部分,那么查询只需要在索引文件上进行,不需要回行到磁盘再找数据.
索引和排序关系,由于索引是已经排好序的,最好排序时使用索引列,让索引覆盖到
冗余索引如果一个索引字段包含或者重复另一个索引我们叫冗余索引,遇到这样的索引删掉。

索引碎片与维护在长期的数据更改过程中, 索引文件和数据文件,都将产生空洞,形成碎片
optimize table 表名
alter table xxx engine innodb
不过这样很耗资源

第五步如果我们前三步优化完网站还是运行很慢
建立MYSQL主从集群 主从配置或者主主配置 或者通过中间软件proxy完成所有服务器的负载均衡
数据库复制实现原理
1:主服务器凡运行语句,都产生一个二进制日志 binlog
2:从服务器不断读取主服务器的binlog
3:从主服务读取到的binlog,转换为自身可执行的relaylog,
4:执行relaylog

其它 事务
事务的4个特性:ACID
原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)
开启事务 start transaction
执行查询 xxxx
提交事务/回滚事务. commit / rollback

总结 最好的优化是不要查询,由于时间原因前面写的详细,后面的只是大概的说了一下,如果又不懂的我们可以一天探讨。

你可以发表评论引用到你的网站或博客,或通过RSS 2.0订阅这个日志的所有评论。
上一篇:
下一篇:
已有3条评论
尚吾网
2014 年 12 月 24 日

爱你不是两三天,每月看你很多遍。

rubber extrusion
2014 年 12 月 25 日

mysql优化,谢谢分享!

瓜丢网
2014 年 12 月 26 日

一直在寻找这个,十分感谢

我来说两句

  Ctrl+Enter