• 公众号回复关键词获取免费学习资料,加入前后端技术交流群和副业群。新建立的副业Q群:735764906。

数据库的操作越来越成为整个应用的性能瓶颈,这对于Web应用尤其明显。关于数据库的性能,这并不只是DBA需要关心的,而更是后端开发需要去关注的事情。

所以本文讲解MySQL在各个方面的优化方向,方便后端开发人员在调优和问题排查过程中找到切入点。

本文目录如下:

目录

服务器硬件的优化

MySQL数据库配置优化

CentOS系统针对mysql的参数优化

内核相关参数(/etc/sysctl.conf)

增加资源限制(/etc/security/limit.conf)

磁盘调度策略

MySQL的参数配置

MySQL表结构与SQL优化

索引优化规则

1.使用最左前缀规则

2.模糊查询不能利用索引(like '%XX'或者like '%XX%')

3.不要过多创建索引

4.索引长度尽量短

5.索引更新不能频繁

6.索引列不能参与计算

查询时的优化

小表驱动大表

避免全表扫描

避免mysql放弃索引查询

使用覆盖索引,少使用select*

order by的索引生效

不正确的使用导致索引失效

for update锁表

其他优化

开启慢查询

实时获取有性能问题的SQL

垂直分割

拆分执行时间长的DELETE或INSERT语句

好书推荐

高性能MySQL

阿里巴巴Java开发手册


本文配置均为参考值,实际设置要参考基准测试或现场环境。

服务器硬件的优化

提升硬件设备,例如选择尽量高频率的内存(频率不能高于主板的支持)、提升网络带宽、使用SSD高速磁盘、提升CPU性能等。

CPU的选择:

  • 对于数据库并发比较高的场景,CPU的数量比频率重要。

  • 对于CPU密集型场景和频繁执行复杂SQL的场景,CPU的频率越高越好。

MySQL数据库配置优化

  • 表示缓冲池字节大小。

  • 用来控制redo log刷新到磁盘的策略。

  • 每提交1次事务同步写到磁盘中,可以设置为n。

  • 脏页占innodb_buffer_pool_size的比例时,触发刷脏页到磁盘。推荐值为25%~50%。

  • 后台进程最大IO性能指标。

  • 指定innodb共享表空间文件的大小。

  • 慢查询日志的阈值设置,单位秒。

  • mysql复制的形式,row为MySQL8.0的默认形式。

  • 调高该参数则应降低interactive_timeout、wait_timeout的值。

  • 过大,实例恢复时间长;过小,造成日志切换频繁。

  • 全量日志建议关闭。

CentOS系统针对mysql的参数优化

本节只提及部分重要的参数,更全面的参数优化,可以查看这本书。

内核相关参数(/etc/sysctl.conf)

以下参数可以直接放到sysctl.conf文件的末尾。

1.增加监听队列上限:

net.core.somaxconn = 65535net.core.netdev_max_backlog = 65535net.ipv4.tcp_max_syn_backlog = 65535

2.加快TCP连接的回收:

net.ipv4.tcp_fin_timeout = 10net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_tw_recycle = 1

3.TCP连接接收和发送缓冲区大小的默认值和最大值:

net.core.wmem_default = 87380net.core.wmem_max = 16777216net.core.rmem_default = 87380net.core.rmem_max = 16777216

4.减少失效连接所占用的TCP资源的数量,加快资源回收的效率:

net.ipv4.tcp_keepalive_time = 120net.ipv4.tcp_keepalive_intvl = 30net.ipv4.tcp_keepalive_probes = 3

5.单个共享内存段的最大值:

kernel.shmmax = 4294967295

  1. 这个参数应该设置的足够大,以便能在一个共享内存段下容纳整个的Innodb缓冲池的大小。

  2. 这个值的大小对于64位linux系统,可取的最大值为(物理内存值-1)byte,建议值为大于物理内存的一半,一般取值大于Innodb缓冲池的大小即可。

6.控制换出运行时内存的相对权重:

vm.swappiness = 0

这个参数当内存不足时会对性能产生比较明显的影响。(设置为0,表示Linux内核虚拟内存完全被占用,才会要使用交换区。)

Linux系统内存交换区:在Linux系统安装时都会有一个特殊的磁盘分区,称之为系统交换分区。使用 free -m 命令可以看到swap就是内存交换区。作用:当操作系统没有足够的内存时,就会将部分虚拟内存写到磁盘的交换区中,这样就会发生内存交换。

如果Linux系统上完全禁用交换分区,带来的风险:

  1. 降低操作系统的性能

  2. 容易造成内存溢出,崩溃,或都被操作系统kill掉

增加资源限制(/etc/security/limit.conf)

打开文件数的限制(以下参数可以直接放到limit.conf文件的末尾):

* soft nofile 65535* hard nofile 65535

*:表示对所有用户有效soft:表示当前系统生效的设置(soft不能大于hard )hard:表明系统中所能设定的最大值nofile:表示所限制的资源是打开文件的最大数目65535:限制的数量

以上两行配置将可打开的文件数量增加到65535个,以保证可以打开足够多的文件句柄。

注意:这个文件的修改需要重启系统才能生效。

磁盘调度策略

1.cfq (完全公平队列策略,Linux2.6.18之后内核的系统默认策略)

该模式按进程创建多个队列,各个进程发来的IO请求会被cfq以轮循方式处理,对每个IO请求都是公平的。该策略适合离散读的应用。

2.deadline (截止时间调度策略)

deadline,包含读和写两个队列,确保在一个截止时间内服务请求(截止时间是可调整的),而默认读期限短于写期限。这样就防止了写操作因为不能被读取而饿死的现象,deadline对数据库类应用是最好的选择。

3.noop (电梯式调度策略)

noop只实现一个简单的FIFO队列,倾向饿死读而利于写,因此noop对于闪存设备、RAM及嵌入式系统是最好的选择。

4.anticipatory (预料I/O调度策略)

本质上与deadline策略一样,但在最后一次读操作之后,要等待6ms,才能继续进行对其它I/O请求进行调度。它会在每个6ms中插入新的I/O操作,合并写入流,用写入延时换取最大的写入吞吐量。anticipatory适合于写入较多的环境,比如文件服务器。该策略对数据库环境表现很差。

查看调度策略的方法:

cat /sys/block/devname/queue/scheduler

修改调度策略的方法:

echo <schedulername> > /sys/block/devname/queue/scheduler

MySQL的参数配置

请阅读笔者的CSDN博客《MySQL服务器参数配置》,点击跳转。如无法跳转,请查看原文即可查看。

MySQL表结构与SQL优化

索引优化规则

结合笔者的上一篇博客——《彻底搞懂MySQL的索引》,可以很容易理解索引优化的原理。

1.使用最左前缀规则

如果使用联合索引,要遵守最左前缀规则。即要求使用联合索引进行查询,从索引的最左前列开始,不跳过索引中的列并且不能使用范围查询(>、<、between、like)。

2.模糊查询不能利用索引(like '%XX'或者like '%XX%')

假如索引列code的值为'AAA','AAB','BAA','BAB',如果where code like '%AB'条件,由于条件前面是模糊的,所以不能利用索引的顺序,必须逐个查找,看是否满足条件。这样会导致全索引扫描或者全表扫描。

如果是where code like 'A%',就可以查找code中A开头的数据,当碰到B开头的数据时,就可以停止查找了,因为后面的数据一定不满足要求,这样可以提高查询效率。

3.不要过多创建索引

过多的索引会占用更多的空间,而且每次增、删、改操作都会重建索引。

在一般的互联网场景中,查询语句的执行次数远远大于增删改语句的执行次数,所以重建索引的开销可以忽略不计。但在大数据量导入时,可以考虑先删除索引,批量插入数据,然后添加索引。

尽量扩展索引,比如现有索引(a),现在又要对(a,b)进行索引,那么只需要修改索引(a)即可,避免不必要的索引冗余。

4.索引长度尽量短

短索引可以节省索引空间,使查找的速度得到提升,同时内存中也可以装载更多的索引键值。

太长的列,可以选择建立前缀索引

5.索引更新不能频繁

更新非常频繁的数据不适宜建索引,因为维护索引的成本。

6.索引列不能参与计算

不要在索引列上做任何的操作,包括计算、函数、自动或者手动类型的转换,这样都会导致索引失效。

比如,where from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大。所以语句应该写成where create_time = unix_timestamp(’2014-05-29’)。

查询时的优化

小表驱动大表

第一张表是全表索引(要以此关联其他表),其余表的查询类型type为range(索引区间获得),也就是6 * 1 * 1,共遍历查询6次即可;

建议使用left join时,以小表关联大表,因为使用join的话,第一张表是必须全扫描的,以少关联多就可以减少这个扫描次数.

这里所说的表的type,指的是explain执行计划中的结果字段。详情点击查看,explain的属性详解与提速百倍的优化示例

避免全表扫描

mysql在使用不等于(!=或者<>)的时候无法使用导致全表扫描。在查询的时候,如果对索引使用不等于的操作将会导致索引失效,进行全表扫描

避免mysql放弃索引查询

如果mysql估计使用全表扫描要比使用索引快,则不使用索引。(最典型的场景就是数据量少的时候)

使用覆盖索引,少使用select*

需要用到什么数据就查询什么数据,这样可以减少网络的传输和mysql的全表扫描。

尽量使用覆盖索引,比如索引为name,age,address的组合索引,那么尽量覆盖这三个字段之中的值,mysql将会直接在索引上取值(using index),并且返回值不包含不是索引的字段。

如果查询select的列过多,覆盖索引的效率会大大下降,这时可以考虑放弃覆盖索引查询。

order by的索引生效

order by排序应该遵循最佳左前缀查询,如果是使用多个索引字段进行排序,那么排序的规则必须相同(同是升序或者降序),否则索引同样会失效。

不正确的使用导致索引失效

如果查询中有某个列的范围查询,则其右边所有列都无法使用索引。

for update锁表

A, B两个事务分别使用select ... where ... for update进行查询时:

  1. A事务执行查询操作的时候,如果这个查询结果为空,无论where条件是否是索引字段,B事务执行查询操作时,不会被阻塞。

  2. A事务执行查询操作的时候,当where条件是索引字段,则B事务执行同样的查询时会被行加锁阻塞;当where条件不是索引字段,则B事务执行有结果集的查询,都会被阻塞。

for update操作一定要谨慎,之前笔者就遇到过for update产生gap锁,导致后续请求阻塞的问题。之后的博客单独介绍MySQL的锁机制,同时讲解下更多死锁的情况。

其他优化

开启慢查询

开启慢查询日志,可以让MySQL记录下查询超过指定时间的语句,通过定位分析性能的瓶颈,更好的优化数据库系统的性能。

以后单独的博客进行详细的讲解

实时获取有性能问题的SQL

利用information_schema数据库的processlist表,实时查看执行时间过长的线程,定位需要优化的SQL。

例如下面的SQL的作用是查看正在执行的线程,并按Time倒排序,查看执行时间过长的线程。

select * from information_schema.processlist where Command != 'Sleep' order by Time desc;

垂直分割

“垂直分割”是一种把数据库中的表,按列变成几张表的方法。这样可以降低表的复杂度和字段的数目,从而达到优化的目的。

示例一:

在Users表中有一个字段是address,它是可选字段,并且不需要经常读取或是修改。

那么,就可以把它放到另外一张表中,这样会让原表有更好的性能。

示例二:

有一个叫 “last_login”的字段,它会在每次用户登录时被更新,每次更新时会导致该表的查询缓存被清空。

所以,可以把这个字段放到另一个表中。

这样就不会影响对用户ID、用户名、用户角色(假设这几个属性并不频繁修改)的不停地读取了,因为查询缓存会增加很多性能。

拆分执行时间长的DELETE或INSERT语句

避免在生产环境上执行会锁表的DELETE或INSERT的操作。一定把其拆分,或者使用LIMIT条件也是一个好的方法。

下面是一个示例:

while (1) {  //每次只做1000条 mysql_query("DELETE FROM logs WHERE log_date &lt;= '2009-11-01' LIMIT 1000");  if (mysql_affected_rows() == 0) { // 没得可删了,退出!  break;  }   // 每次都要休息一会儿    usleep(50000);
}

好书推荐

高性能MySQL

MySQL优化绝不是一篇博客就能讲解全面的,所以笔者隆重推荐《高性能mysql》一书,如果没看过的话,一定要看。

图书简介:

《高性能MySQL(第3版)》是MySQL领域的经典之作,拥有广泛的影响力。第3 版更新了大量的内容,不但涵盖了最新MySQL 5.5版本的新特性,也讲述了关于固态盘、高可扩展性设计和云计算环境下的数据库相关的新内容,原有的基准测试和性能优化部分也做了大量的扩展和补充。全书共分为16章和6个附录,内容涵盖MySQL架构和历史,基准测试和性能剖析,数据库软硬件性能优化,复制、备份和恢复,高可用与高可扩展性,以及云端的mysql和mysql相关工具等方面的内容。每一章都是相对独立的主题,读者可以有选择性地单独阅读。

阿里巴巴Java开发手册

除了本文提到的索引规则,《阿里巴巴Java开发手册》里面有关MySQL的规范接近50条,每一条也都值得琢磨。

更多内容,欢迎关注微信公众号:全菜工程师小辉。后台回复关键词领取免费学习资料。

一文搞定MySQL性能调优相关推荐

  1. MySQL mysql性能调优

    MySQL性能调优,SQL优化.索引优化 慢查询日志 当查询超过一定的时间没有返回结果的时候,才会记录到慢查询日志中.默认不开启. 采样的时候手工开启.可以帮助我们找出执行慢的 SQL 语句 查看慢 ...

  2. MySQL性能调优与架构设计——第11章 常用存储引擎优化

    第11章 常用存储引擎优化 前言: MySQL 提供的非常丰富的存储引擎种类供大家选择,有多种选择固然是好事,但是需要我们理解掌握的知识也会增加很多.每一种存储引擎都有各自的特长,也都存在一定的短处. ...

  3. mysql性能调优 高可用_MySQL性能调优与架构设计——第 17 章 高可用设计之思路及方案...

    第 17 章 高可用设计之思路及方案 前言: 数据库系统是一个应用系统的核心部分,要想系统整体可用性得到保证,数据库系统就不能出现任何问题.对于一个企业级的系统来说,数据库系统的可用性尤为重要.数据库 ...

  4. 转】MYSQL性能调优与架构设计之select count(*)的思考

    原博文出自于: http://blog.fens.me/category/%E6%95%B0%E6%8D%AE%E5%BA%93/page/5/ 感谢! Posted: Feb 7, 2013 Tag ...

  5. MySQL性能调优与架构设计——第4章 MySQL安全管理

    第4章 MySQL安全管理 前言 对于任何一个企业来说,其数据库系统中所保存数据的安全性无疑是非常重要的,尤其是公司的有些商业数据,可能数据就是公司的根本,失去了数据的安全性,可能就是失去了公司的一切 ...

  6. MySQL性能调优与架构设计——第5章 备份与恢复

    第5章 备份与恢复 前言 数据库的备份与恢复一直都是 DBA 工作中最为重要的部分之一,也是基本工作之一.任何正式环境的数据库都必须有完整的备份计划和恢复测试,本章内容将主要介绍 MySQL数据库的备 ...

  7. MySQL 性能调优之存储引擎

    原文:http://bbs.landingbj.com/t-0-246222-1.html        http://bbs.landingbj.com/t-0-245851-1.html MySQ ...

  8. 经典!《MySQL性能调优手册》高清电子版,限时 3 天免费下载

    点击上方"逆锋起笔",关注领取视频教程 ☞ 程序员进阶必备资源免费送「各种技术!」 ☜ 作为最流行的开源数据库软件之一,MySQL数据库软件已经是广为人知的了,性能调优是MySQL ...

  9. MySQL 性能调优和优化技巧

    介绍 MySQL 是一种流行的开源数据库应用程序,它以一种有意义且易于访问的方式存储和构造数据.对于大型应用程序,庞大的数据量可能会导致性能问题. 本指南提供了一些关于如何提高 MySQL 数据库性能 ...

最新文章

  1. date新的使用方法
  2. IOS使用个推遇到的坑
  3. C# 7中函数多值返回_转自InfoQ
  4. ASP.NET 之异步处理一(Session处理)
  5. 详解「递归」正确的打开方式
  6. VTK修炼之道33:边缘检测_Sobel算子
  7. 通过改进视频质量评估提升编码效率
  8. 判断语句_如何学好C语言判断语句?攻略if语句是第一步
  9. 解决Conda install tensorflow弹窗Python.exe已经停止工作的问题
  10. 【笔记】shell下的主要工具
  11. windows 2008 快速安装RODC
  12. MATLAB 绘图函数总结
  13. (一)数字图像处理基础知识点
  14. Islands 架构原理和实践
  15. dropbox 怎么使用_如何在一台PC上使用多个Dropbox帐户
  16. 一文读懂POE交换机和普通交换机的区别
  17. 如何使用ABP开发一
  18. high sierra php,macOS High Sierra 上测试 Apache 和 PHP 站点
  19. 工厂模式的缺点及解决到生产的应用
  20. Adobe认证专访|003期:跨界摄影师,我眼中的世界与别人不一样

热门文章

  1. Sleuth Kit、Autopsy 的使用
  2. 安抚自己那颗有些恐惧的心
  3. 6.ROSPX4--Pixhawk无人机+A1激光雷达SLAM部署
  4. katalon:赋值方式
  5. http 401错误解析
  6. vscode中PHP语言的自动补齐,vscode怎么自动补全
  7. 临沂3d可视化建模,数字孪生智慧工厂3D模型开发,智慧城市园区三维仿真模型
  8. 计算机网络知识点01——物理媒体(双绞铜线、同轴电缆、光纤、无线电信道)的比较
  9. 程序员去互联网企业还是去当教师,薪资和压力,要是你怎么选呢?
  10. goto 在 linux 里面简单使用