最近听讲了博森瑞老师的mysql优化公开课,这个是我整理的笔记。

现在说一下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。

i

############

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优化--博森瑞-czxin788-ITPUB博客
http://blog.itpub.net/28916011/viewspace-1758440/

mysql优化【转】的更多相关文章

  1. MySQL优化聊两句

    原文地址:http://www.cnblogs.com/verrion/p/mysql_optimised.html MySQL优化聊两句 MySQL不多介绍,今天聊两句该如何优化以及从哪些方面入手, ...

  2. 0104探究MySQL优化器对索引和JOIN顺序的选择

    转自http://www.jb51.net/article/67007.htm,感谢博主 本文通过一个案例来看看MySQL优化器如何选择索引和JOIN顺序.表结构和数据准备参考本文最后部分" ...

  3. mysql 优化

    1.存储过程造数据 CREATE DEFINER=`root`@`localhost` PROCEDURE `generate_test_data`(`n` int) begin declare i ...

  4. mysql优化笔记之分页

    过年闲得蛋疼,于是看看mysql优化,看了网上好多关于分页的优化方法,但是呢,我亲自试上一把的时候,没有出现他们说的现象...难道是我的机器问题么? 下面看看我的实践记录,希望看到的加入进来交流一下O ...

  5. MySQL优化概述

    一. MySQL优化要点 MySQL优化是一门复杂的综合性技术,主要包括: 1 表的设计合理化(符合 3NF,必要时允许数据冗余) 2.1 SQL语句优化(以查询为主) 2.2 适当添加索引(主键索引 ...

  6. MySQL优化实例

    这周就要从泰笛离职了,在公司内部的wiki上,根据公司实际的项目,写了一些mysql的优化方法,供小组里的小伙伴参考下,没想到大家的热情很高,还专门搞了个ppt讲解了一下. 举了三个大家很容易犯错的地 ...

  7. Mysql优化系列(2)--通用化操作梳理

    前面有两篇文章详细介绍了mysql优化举措:Mysql优化系列(0)--总结性梳理Mysql优化系列(1)--Innodb引擎下mysql自身配置优化 下面分类罗列下Mysql性能优化的一些技巧,熟练 ...

  8. mysql优化记录

    老板反应项目的反应越来越慢,叫优化一下,顺便学习总结一下mysql优化. 不同引擎的优化,myisam读的效果好,写的效率差,使用场景 非事务型应用只读类应用空间类应用 Innodb的特性,innod ...

  9. mysql 优化实例之索引创建

    mysql 优化实例之索引创建 优化前: pt-query-degist分析结果: # Query 23: 0.00 QPS, 0.00x concurrency, ID 0x78761E301CC7 ...

  10. MySQL优化的奇技淫巧之STRAIGHT_JOIN

    原文地址:http://huoding.com/2013/06/04/261 问题 通过「SHOW FULL PROCESSLIST」语句很容易就能查到问题SQL,如下: SELECT post.* ...

随机推荐

  1. 在java中为什么要把main方法定义为一个static方法?

    我们知道,在C/C++当中,这个main方法并不是属于某一个类的,它是一个全局的方法,所以当我们执行的时候,c++编译器很容易的就能找到这个main方法,然而当我们执行一个java程序的时候,因为ja ...

  2. 【bzoj3926】 Zjoi2015—诸神眷顾的幻想乡

    http://www.lydsy.com/JudgeOnline/problem.php?id=3926 (题目链接) 题意 给出一棵树,每个节点有一个编号,范围在${[0,9]}$.一个序列是指树上 ...

  3. bzoj2755【SCOI2012】喵星人的入侵

    输入格式 第一行为三个整数n,m,K,分别表示地图的长和宽,以及最多能放置的炮塔数量. 接下来的n行,每行包含m个字符,‘#’表示地图上原有的障碍,‘.’表示该处为空地,数据保证在原地图上存在S到T的 ...

  4. CentOS-5的yum源无法使用问题

    CentOS-5的yum源无法使用问题 [root@37wan ~]# yum -y install gcc Loaded plugins: fastestmirror Determining fas ...

  5. 解决Anaconda4.2 Navigator打不开的问题

    参照博客:http://blog.csdn.net/k3v1n1990s/article/details/72975528?utm_source=itdadao&utm_medium=refe ...

  6. golang 安装一个项目下的所有依赖

    go get -v ./...

  7. ACF/PACF,残差白噪声的检验问题

    关于自相关.偏自相关: 一.自协方差和自相关系数       p阶自回归AR(p)       自协方差 r(t,s)=E[X(t)-EX(t)][X(s)-EX(s)]       自相关系数ACF ...

  8. 初学SQL语句练习2

    -- 子查询 --单行子查询-- 查询出所有比雇员姓名为“CLARK ”工资高的员工的信息 SELECT * FROM EMP WHERE SAL > (SELECT SAL FROM EMP ...

  9. python 常用模块之os

    1.权限判断 bool: os.access('/python/test.py',os.F_OK) #是否存在 bool: os.access('/python/test.py',os.R_OK) # ...

  10. python中几种常用的数据类型

    1.字典 字典的创建: dict1=dict((('name','PIG'),)),其中第一层()代表里面的内容是dict函数的输入参数.第二层和第三层代表字典中的各元素,也就是key和value组合 ...