mysql优化--博森瑞
http://blog.itpub.net/28916011/viewspace-1758440/
现在说一下mysql的内存和I/O方面的两个特点。
一、 mysql内存特点:
1、 也有全局内存和每个session的内存(每个session类似于oracle的sga和pga),但是针对每个session的内存,我们不要给它分配过大。如果对每个session的内存分配过大,会造成oom的发生。在高并发下,增加物理内存就可以减少物理I/O。所以mysql的内存管理比oracle简单一些。
2、在oracle里面有library cache,用来缓存执行计划的。但是mysql不会缓存执行计划,mysql有类似于oracle的Qcache,Qcache是用来缓存sql语句的,但是在生产中建议关掉此功能,因为该功能很鸡肋,它的功能体现不了那么大的作用。
3、mysql的查询分析器很高效,mysql不缓存执行计划,但是并不会出现像oracle那种硬解析的问题。
4、对于内存方面的分配,如果是单实例的Mysql,建议分配50%到70%的物理内存给mysql。
二、mysql I/O方面的特点
mysql有binlog、undo log和redo log三个日志文件都是顺序写I/O的方式。mysql的数据文件是包含着随机写I/O和顺序写I/O的。
目前mysql有innodb和myisam存储引擎。有人可能会说myisam的存储引擎要比innodb的存储引擎快。其实并不是这样的。为什么这么说呢哈?innodb主要根据主键检索数据时很快,因为主键里包含行的数据信息,而且,对于innodb,它是双链表结构, 所以他很快就能找到数据。另外,Innodb既缓存数据文件,也缓存索引文件。但是针对myisam来说呢,myisam只缓存索引文件。所以,一个很简单的道理,你说是从内存读快,还是从磁盘读快。答案肯定是从内存读取快。所以结论就是,Innodb要比Myisam存储引擎快。
优化思路:
1、发现问题的过程
当数据库慢了,要搞清是什么问题导致系统慢了,是系统的问题,还是开发的问题,还是数据库的问题;
2、找到问题后,锁定问题瓶颈点;
锁定瓶颈点的过程,分为两个层面。一个是系统层面,一个是数据库层面。
2.1 系统层面
系统层面就需要我们学习一些linux方面的知识,利用linux的知识,来锁定问题的瓶颈在哪。top命令可以看哪个进程占用cpu最高,查看负载,可以查看内存。
vmstat可以查看内存、cpu、i/o。
sar –u 查看cpu
sar -d 查看io
sar -r 查看内存
2.2数据库层面
现在Mysql默认存储引起是innodb。
1、show engine innodb status
通过show innodb status看锁的情况,看数据有没有锁,有没有死锁,有没有事务状态,看看一些页的情况,看看现在有没有老页和新页的移动。
2、slow log
看慢日志,制定时间,有好多工具可以分析慢日志(如percona公司的),找到top10最慢的sql(一般优先处理频率最高的前十条SQL语句)
也可以通过图形化的工具,找到最慢的sql,然后找开发沟通,商讨是在业务上更改呢,还是针对这条SQL来进行优化。我们的目的就是让sql越简单越好。
3、show global status
show global status查看数据库整体的性能,看哪个点需要调整一下,看碎片是如何产生,碎片产生多少,如何清理碎片。看每秒钟产生的TPS有多少。
4、 show processlist
show processlist查看整个mysql链接的一个情况,注意看wait timeout 和inactive timeout ,主要减少不活跃的连接,这样可以把那些消耗的内存收回,从而防止omq的发生。
5、Pt-ioprofile
pt-ioprofile是第三方工具,查看innodb内部有哪些表是最活跃的,因为大部分的优化,都是在SQL瓶颈点。当我们锁定到这些表,我们就可以针对这些表做一些文章了,看这些表是否需要添加索引,是否进行碎片的整理。所以这个工具也很重要。
3、 优化方法的初定
我们锁定到了问题的瓶颈点了,就需要制定优化方案。
4、 制定优化方案。
5、优化方案的测试
我们不能因为优化一个问题点,影响其他的业务。所以锁定问题是从面到点,但是优化测试是从点到面。我们只要把这个点解决问题了,而不要影响全面。所以测试时一定要找测试环境,方案能真正在生产线上实施再实施。
6、方案的实施
7、问题解决了
一定要做好记录,想清楚为什么发生这样的问题,避免下次再发生。这也是考验一个人的好的学习方式。
在硬件角度的优化。
从系统bios层面
从系统bios层面,有个参数叫dapc,它表示每瓦的电能都能产生最大的功效,可以让cpu发挥它最大的功效。
在bios层面,还有个参数是内存频率,一定要调成max performance。
在bios层面还有一个cae处理器,当它处于闲置状态的时候,我们可以禁用处理器,使其处于最低的状态。
关于TPS高,业务高
关于TPS高,业务高的一个情况,这种情况一定要配置阵列卡,一定要配置cache模块和bbu模块。bbu模块是用来提供我后备的电量,当机器断电了,我的bbu模块可以去充当电源,保证数据不会丢失,使数据写到cache里面。现在新的服务器都是电容模式的bbu了,性能会更好。
关于阵列卡策略的问题
关于阵列卡策略的问题,一定要选择wb(write bike),就是当写数据的时候,一定要先写到cache卡里面,然后通过阵列卡把数据刷到磁盘,这样能提高我们的IOPS。一定要禁用 wthrow,因为这种直接写磁盘是非常耗性能的。
关于关闭预读功能
关于关闭预读功能,就是让缓存踏踏实实做写缓存的作用。不要开启预读,不要开启数据页,到我的cache里面,这么做没有任何作用。
关于阵列级别的选择
关于阵列级别的选择,对于mysql数据库,建议用raid 1+0。
有人说,用raid5也不错,但是raid5的写乘法数据是4。为什么是4呢,因为raid5有读数据,读校验位、写数据,写校验位。但是raid10,它只有双写,也就是raid10的系数是2。所以raid10写的i/o一定要比raid5高,不过raid5读i/o比raid10可能好一些,但是针对oltp这种系统,推荐用raid10。
关于磁盘上的策略
关于关闭磁盘上的策略,一定要关闭磁盘上的cache策略。因为我们没有必要开它,这样可以防止丢失数据。
关于选盘的问题
建议上SSD或PCIE-SSD的磁盘,这样可以提高iops上百倍或者上千倍。
关于swappiness值大小的调整
swappiness值大小对于我们如何使用swap分区是有很多联系的。当swappiness设置为0,就是充分利用虚拟内存。当swappines设置为100,表示能用swap分区,就用swap分区。
在redhat 6版本之前,swappiness可以设置成0,;但是大于redhat6最好设置成10;到了redhat 7以上,一定要谨慎设置swappiness设置成0,因为如果设置成0了,在redhat 7可能会发生omq。
关于I/O调度器的选择
IO调度器,首选deadline,其次用noop,不要用默认的cfq,默认是非常的不好的。
关于文件系统的选择
首先xfs,其次ext4。
innodb是Mysql的默认存储引擎。影响innodb引擎最重要的参数是innodb_buffer_pool_size,它就相当于oracle的buffer cache,是用来缓存数据用的。
在单实例的mysql,最好设置innodb_buffer_pool_size设置为50%~70%的物理内存大小。
innodb_data_file_path,该参数就是分配共享表空间的大小。它默认是10m。但是我们建议将其设置成1G,这样可以避免后期数据暴涨很消耗性能。
innodb_log_file_size,该参数不要设置的过大,因为该参数相当于oracle里面的redo。如果把该参数设置的过大,当数据库crash的时候,恢复数据就会很慢。
transaction_isolation,表示事务隔离级别。对于mysql需要什么样的事务隔离级别,是需要一步一步去选择的。对于oracle来讲,事务隔离级别就是默认的提交读。但是对于mysql,有默认的提交读,也有可重复读,还有脏读和串读。建议使用Mysql的可重复读(r模式),因为这种模式可以保证数据的一致性,可以避免发生一个事务提交了,在另一个事务中能看到他提交的东西。如果事务提交了,在另外一个事务中能看到他提交的东西,这样就违背了事务一致性的情况的。
sort_buffer_size、read_buffer_size、join_buffer_size三个参数,可以理解为oracle的pga。这三个参数不用设置过大,大概几兆,几十兆就行。另外oracle的pga也不要设置的过大。
general_log,log_bin,sync_binlog,long_query_time,interactive_timeout,wait_timeout,max_connections
在生产上,不要开全日志(general_log),因为开了全日志,它就会记录全部的sql语句,这样很影响mysql性能。
对于binlog日志,一定要开此功能,因为这样可以实现复制的功能,也可以实现binlog恢复的功能。
对于sync_binlog,该参数数值的大小,关系到数据库写binlog情况的问题。
sync_binlog=0,表示我每一秒刷一次binlog,sync_binlog=1表示每秒我都刷,保证他不会丢;当sync_binlog=2,表示交给操作系统,数据库不管了。
对于long_query_time,表示慢查询时间的一个情况,可以设置0.xxxx秒的慢查询。对出现频率高的慢sql进行优化。
可以通过show processlist看一些交互式和非交互式的时间等待。对于interactive_timeout和wait_timeout这两个参数我们不要设置的过大,一般这两个值设置的一样,在没有连接池的情况,设置成5分钟就行了。
max_connections,当用户连接数超过这个max_connections时,会报错。但注意,报错时,不要盲目的增大max_connections这个参数。因为如果max_connections设置的过大,会发生数据库被连暴了,塌了的情况,是很危险。那么我们应该如何调整呢?其实出现这种情况会联系到好多的参数的,比如可以减少并发参数的值来减少连接数,或者观察数据库sql语句,分析到底是业务的问题还是数据库的问题。不要什么事情都往自己身上揽,拿出证据,证明这个问题就不是我DBA的问题。
选择存储引擎,是针对业务来讲。针对oltp 默认就是Innodb。到了mysql 5.7有可能myisam会消失。
innodb存储引擎支持事务,支持行锁,锁的粒度更低,所以并发性很好,当发生故障可以根据redo和Undo进行恢复。Innodb是缓存数据和索引的,但是Myisam只缓存索引,而且myisam的数据和索引是分开的。
一定要设置自增主键。如果你不设置自增主键,也没有关系,这时候Mysql会给它一个6字节的主键,但是这样会很消耗性能的。所以设置自增主键是一个必须的选项。
关于时间日期,ipv4类型和数据类型可以用int
避免使用text/blob这种大数据类型。如果非要用大数据类型,可以单独把大数据类型放在一张表上存储。
定义字段的时候尽量要定义Not null,因为索引是不含Null字段的。
选择性低的字段不要创建索引,像男女这样的字段不要创建索引,创建索引没有意义。因为mysql优化器是很智能的,重复值出现很多,mysql可能就不走索引,而是走全表扫描了。
对于排序和分组字段上,一定要创建索引。
索引不要太多,因为update,会使索引的页进行翻转,对性能有很大的下降。
联合索引优于单列索引,联合索引可以缩短整个段池搜索的一个范围,它比单列索引要好。
像一些字符类型,如果可能只用到前面几个字符,而不需要整个字段建索引,这叫前缀索引,我们可以建立一个前缀索引,我只搜那几个字段。
索引扫描记录的述超过30%,就会走全表扫描
模糊匹配查询的双%%不会用到索引的。但是去掉左边的%,%号在最后一位可能会用到索引。
联合索引,第一个查询条件如果不是最做索引列,也不会用到索引,这就是最左前缀原则。
联合索引,如果第一个索引列使用范围查询(> 、=、<、>=、<=),那用到索引也是部分索引,有可能只用到第一个索引了,后面的索引数据库都用不到。
两个独立的索引,一个用来检索,一个用来排序,可能只用到一个。mysql 5.6有ITC这项功能。
最忌讳在索引的字段上使用函数,这样是不会走索引的。
Q&A
sga是内存全局区,pga是用户的一个session连接上数据库单独分配给的内存。
mysql用的最多的集群是MHA。oracle的集群是RAC。
为什么会产生死锁?就是因为共抢一块东西,你要我的东西,我又要你的东西,从而造成死循环,用show innodb status定位死锁产生在哪。
最好关闭磁盘的cache策略,因为写在cache里面,容易发生数据丢失,所以建议关闭磁盘的cache策略。
有问题留言,
保证业务的稳定,保证数据库快速。
主从分离和DBA没有关系,只需要开发在代码里面写好了。
现在mysql架构,就是用MHA。
不是说数据量大了,就进行优化,而是出现性能问题了再进行优化。看索引建没建。
mysql优化--博森瑞的更多相关文章
- mysql优化【转】
最近听讲了博森瑞老师的mysql优化公开课,这个是我整理的笔记. 现在说一下mysql的内存和I/O方面的两个特点. 一. mysql内存特点: 1. 也有全局内存和每个session的内存(每个s ...
- MySQL优化聊两句
原文地址:http://www.cnblogs.com/verrion/p/mysql_optimised.html MySQL优化聊两句 MySQL不多介绍,今天聊两句该如何优化以及从哪些方面入手, ...
- 0104探究MySQL优化器对索引和JOIN顺序的选择
转自http://www.jb51.net/article/67007.htm,感谢博主 本文通过一个案例来看看MySQL优化器如何选择索引和JOIN顺序.表结构和数据准备参考本文最后部分" ...
- mysql 优化
1.存储过程造数据 CREATE DEFINER=`root`@`localhost` PROCEDURE `generate_test_data`(`n` int) begin declare i ...
- mysql优化笔记之分页
过年闲得蛋疼,于是看看mysql优化,看了网上好多关于分页的优化方法,但是呢,我亲自试上一把的时候,没有出现他们说的现象...难道是我的机器问题么? 下面看看我的实践记录,希望看到的加入进来交流一下O ...
- MySQL优化概述
一. MySQL优化要点 MySQL优化是一门复杂的综合性技术,主要包括: 1 表的设计合理化(符合 3NF,必要时允许数据冗余) 2.1 SQL语句优化(以查询为主) 2.2 适当添加索引(主键索引 ...
- MySQL优化实例
这周就要从泰笛离职了,在公司内部的wiki上,根据公司实际的项目,写了一些mysql的优化方法,供小组里的小伙伴参考下,没想到大家的热情很高,还专门搞了个ppt讲解了一下. 举了三个大家很容易犯错的地 ...
- Mysql优化系列(2)--通用化操作梳理
前面有两篇文章详细介绍了mysql优化举措:Mysql优化系列(0)--总结性梳理Mysql优化系列(1)--Innodb引擎下mysql自身配置优化 下面分类罗列下Mysql性能优化的一些技巧,熟练 ...
- mysql优化记录
老板反应项目的反应越来越慢,叫优化一下,顺便学习总结一下mysql优化. 不同引擎的优化,myisam读的效果好,写的效率差,使用场景 非事务型应用只读类应用空间类应用 Innodb的特性,innod ...
随机推荐
- BZOJ_3172_[TJOI2013]_单词_(AC自动机)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3172 \(n\)个单词组成一篇文章,求每个单词在文章中出现的次数. 分析 这道题很像BZOJ_ ...
- [2015编程之美] 资格赛C
#1150 : 基站选址 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 需要在一个N × M的网格中建立一个通讯基站,通讯基站仅必须建立在格点上. 网格中有A个用户,每个 ...
- The new Portable Class Library for SQLite z
Microsoft Open Technologies has recently released a Portable Class Library for SQLite. Thanks to it, ...
- 获取EntityFrameWork返回的错误和ModelState中的错误
都是通过循环才能找到具体的错误信息 具体方法参见这两篇文章: EntityFrameWork: http://www.cnblogs.com/shouzheng/archive/2012/04/19/ ...
- 如何实现CSS居中?–CSS居中常用方法
来源:http://www.ido321.com/824.html 一.水平居中 1.内联元素居中:相对父级块级元素居中对齐 1: .center-children { 2: text-align: ...
- JDK1.5新特性(五)……Typesafe Enums
援引 Typesafe Enums - This flexible object-oriented enumerated type facility allows you to create enum ...
- 使用Genymotion作Android开发模拟器:安装Genymotion、部署Genymotion Vitrue Device、安装Genymotion eclipse插件
偶然听说Genymotion Android模拟器非常强大,到网上了解一番后,决定从AVD又慢又卡中解脱出来,折腾了半天终于部署好了,体验了一下,果然启动快,运行流畅,现在总结一下经验教训,供大家参考 ...
- C#中使用DLL文件
首先,我们需要在C++程序中导出DLL文件.我使用的是Visual Studio开发,把项目"属性"中的“配置类型”改为"动态库dll",然后添加如下导出代码: ...
- 使用Mono Cecil 动态获取运行时数据 (Atribute形式 进行注入 用于写Log) [此文报考 xxx is declared in another module and needs to be imported的解决方法]-摘自网络
目录 一:普通写法 二:注入定义 三:Weave函数 四:参数构造 五:业务编写 六:注入调用 7. 怎么调用别的程序集的方法示例 8. [is declared in another module ...
- RecyclerView设置verticalSapcing等
RecyclerView没有像GridView那样有提供verticalSpacing属性,上StackOverflow找到了一种替代方法,代码如下 public class SpacesItemDe ...