MySQL性能优化方案总结

对MySQL进行优化主要能够从如下几个方面进行,
效果: SQL语句和索引 > 数据库对象:表结构、字段类型、存储引擎 > 配置 > 硬件
但成本从低到高。算法

1.SQL和索引优化

1.1SQL

1.1.1优化SQL语句的通常步骤:

①经过show status 命令了解各类SQL的执行效率,数据库

show [session | global] status;

能够根据须要加上参数来显示session级(当前链接,默认)和global级(自数据库上次启动至今)的统计结果。
eg:缓存

show status like 'Com_%';

显示当前链接全部统计参数的值。
Com_xxx表示每一个xxx语句执行的次数,一般须要注意的是下面几个参数:
Com_select/Com_insert/Com_update/Com_delte。服务器

②定位执行效率较低的SQL语句
·经过show processlist命令实时查看当前SQL的执行状况;
·经过慢查询日志(结束之后记录)定位出现的问题。网络

③经过explain 或 desc分析低效SQL的执行计划
select_type(simple/primary/union/subquery)/table/type/possible_keys/key/key_len/rows/extrasession

④经过show profile 分析SQL
show profile 能帮咱们了解时间都耗费到哪里去了。
MySQL从5.0.37版本开始增长了show profile和show profiles语句的支持,
经过secect @have_profiling命令可以看到当前MySQL是否支持profile,
经过show profiles咱们可以更清楚了解SQL执行的过程,
经过show profile for query咱们能看到执行过程当中线程的每一个状态和消耗的时间。架构

⑤经过trace分析优化器如何选择执行计划
MySQL5.6提供了对SQL的跟踪trace,能帮咱们了解为何优化器选择执行A计划而不是B计划,进一步理解优化器的行为。并发

⑥肯定问题并采起相应的优化措施负载均衡

1.1.2两个简单实用的优化方法

①按期分析和检查表高并发

analyze table tbl_name;
check table tbl_name;

②按期优化表

optimize table tbl_name;

1.1.3经常使用SQL的优化

①优化insert语句
·若是从同一客户端插入不少行,应该尽可能使用多个值表一次性插入;
·若是从不一样客户端插入不少行,可使用insert delayed语句先把数据放在内存的队列中,并不真正写入磁盘,比每条语句分别插入快得多;
·当从一个文本文件装载一个表时,使用load data infile,这一般比使用不少insert 语句快20倍;
·若是在MyISAM表中进行批量插入,能够经过增长bulk_insert_buffer_size变量值的方法来提升速度。

②优化 order by语句
MySQL中有两种排序方式,第一种经过有序索引顺序扫描直接返回有效数据,不须要额外的排序,操做效率较高;第二种对返回的数据进行排序,也就是常说的Filesort排序,全部不是经过索引直接返回排序结果的排序都是filesort排序。
优化目标:尽可能经过索引直接返回有序数据,减小额外的排序。
经过建立合适的索引能减小filesort出现,可是某些状况下,条件限制不能让filesort消失,那就须要想办法加快filesort的操做。filesort有两种排序算法,一种是一次扫描算法(较快),二种是两次扫描算法。适当加大系统变量max_length_for_sort_data的值,可以让MySQL选择更优化的filesort排序算法;适当加大sort_buffer_size排序区,尽可能让排序在内存中完成,而不是经过建立临时表放在文件中进行。尽可能只使用必要的字段,select具体的字段名称,而不是select * 选择全部字段,这样能够减小排序区的使用,提升SQL性能。

③优化group by 语句
MySQL默认对全部group by col1,col2...的字段进行排序,能够指定order by null禁止排序。

④优化嵌套查询
MySQL5.5及如下版本,子查询的效率不如链接查询(join),由于MySQL不须要在内存中建立临时表来完成这个在逻辑上须要两个步骤的查询工做。

⑤优化or 查询
对于含有or的查询子句,若是要利用索引,则or之间的每一个条件列都必须使用索引;若是没有索引,能够考虑增长索引。
MySQL在处理含有or的查询时,实际上对or的各个字段分别查询后的结果进行了union操做。

⑥优化分页查询
·第一种 在索引上完成排序分页操做,而后根据主键关联回原表查询所须要的其余列的内容;
·第二种 在排序字段不会出现重复值的状况下,新增一个参数记录上次查询的最后一条记录,将limit m,n转化成limit n.

⑦使用SQL提示
就是在SQL语句中加入一些认为提示,让MySQL按照特定方案执行,以达到优化操做的目的。
·use index 指定MySQL参考的索引而忽略别的索引
·ignore index 让MySQL忽略某个或某些索引
·force index 强制MySQL使用某个特定的索引

⑧其余
·使用REGEXP,好比代替like.
·使用rand()提取随机行
·表的字段尽可能不使用自增加变量,在高并发的状况下可能会对MySQL的效率有较大影响。

1.2索引优化

MySQL的索引在存储引擎层实现,而不是在服务器层。
能够经过show status like 'Handler_read%'命令来查看索引使用状况。

1.2.1MySQL 中索引的存储类型

MySQL 中索引的存储类型目前有四种(B-Tree、Hash、空间索引R-Tree、全文索引Full-text),具体和表的存储引擎相关;MyISAM 和 InnoDB 存储引擎都支持 B-Tree 和全文索引(Full-text,InnoDB 5.6 +);MyISAM还支持空间索引(R-Tree);Memory/Heap存储引擎能够支持 HASH和 B-Tree 索引,不过只有Memory/Heap支持 Hash索引。

1.2.2MySQL如何使用索引

(1)MySQL使用索引的典型情景
①匹配全值(match the full value)
②匹配值的范围(match a range of values)
③匹配最左前缀(match a leftmost prefix)最左匹配原则是MySQL中B-Tree索引使用的首要原则。
④只查询索引(index only query)固然where子句中要知足最左匹配原则
⑤匹配列前缀(match a column prefix)使用复合索引的第一列的开头一部分
⑥复合索引中,一部分匹配精确内容 and 其余部分匹配一个范围(match one part exactly and match a range on another part)
⑦列名是索引,那么column_name is null就会使用索引,好比where column_name is null
(2)MySQL不使用索引的典型情景
①like "%query"不使用B-Tree索引,但like "query%"会使用B-Tree索引。
②数据类型出现隐式转换的时候也不会使用索引。尤为当列类型是字符串时,必定记得在where条件中把字符串常量值用引号引发来,好比where last_name = '1';
③使用复合索引时,查询条件不包含索引的最左边部分
④用or 分割的条件,若是其中一个列中没有索引,则涉及的另外一个索引也不会被用到。
⑤若是MySQL估计使用索引比全表扫描更慢,则不使用索引。

2.优化数据库对象:表结构、字段类型、存储引擎

2.1表结构

2.1.1三范式和反三范式

2.1.2分区、分表(对表进行水平或者垂直拆分)

2.2字段选择合适的数据类型

procedure analyse() 能够对当前应用的表进行分析,对数据表中列的数据类型提出优化建议。

2.3选择合适的存储引擎

3.优化MySQL server

3.1MySQL内存管理和优化

3.2InnoDB log机制及优化

3.3调整跟并发相关的MySQL参数

(1)max_connections
(2)back_log
(3)table_open_cache
(4)thread_cache_size
(5)innodb_lock_wait_timeout

4.磁盘I/O优化

4.1使用磁盘阵列(RAID)

4.2使用Linux虚拟文件卷模拟RAID

4.3符号链接(Symbolic Links)分布I/O

利用操做系统的符号链接(Symbolic Links)将不一样的数据库、表或索引指向不一样的物理磁盘,从而达到分布磁盘I/O的目的。

4.4禁止操做系统更新文件的atime属性

4.5用裸设备(Raw Device)存放InnoDB的共享表空间

4.6调整I/O调度算法

4.7RAID卡电池的充放电引发的性能波动

4.8NUMA架构优化

非一致存储访问结构(Non-Uniform Memory Access, NUMA)

5.应用优化

5.1使用链接池

5.2减小对MySQL的访问

①理清应用逻辑,能一次取出的数据不用两次;
②使用查询缓存
MySQL的查询缓存(MySQL query cache)是4.1版本以后新增的功能,做用是存储select的查询文本和相应结果。若是随后收到一个相同的查询,服务器会从查询缓存中从新获得查询结果,而再也不须要解析和执行查询。
查询缓存适用于更新不频繁的表,当表更改(包括表结构和数据)后,查询缓存会被清空。
③在应用端增长cache层

④负载均衡负载均衡(Load Balance)是实际应用中使用很是广泛的一种优化方法,它的机制就是利用某种均衡算法,将固定的负载量分布到不一样的服务器上,以此来减轻单台服务器的负载,达到优化的目的。负载均衡能够用在系统中的各个层面中,从前台的 Web 服务器到中间层的应用服务器,最后到数据层的数据库服务器,均可以使用。·利用 MySQL 复制分流查询和更新操做利用 MySQL 的主从复制能够有效地分流更新操做和查询操做,具体的实现是一个主服务器承担更新操做,而多台从服务器承担查询操做,主从之间经过复制实现数据的同步。经过复制来分流查询和更新是减小主数据库负载的一个经常使用方法,可是这种办法也存在一些问题,最主要的问题是当主数据库上更新频繁或者网络出现问题的时候,主从之间的数据可能存在比较大的延迟更新,从而形成查询结果和主数据库上有所差别。所以在设计应用的时候须要有所考虑。

相关文章
相关标签/搜索