这是个人第83篇原创文章java

做者 | 王磊mysql

来源 | Java中文社群(ID:javacn666)web

转载请联系受权(微信ID:GG_Stone)

年少不知优化苦,遇坑方知优化难。——村口王大爷

sql

全文内容预览:数据库

我以前有不少文章都在讲性能优化的问题,好比下面这些:数组

固然,本篇也是关于性能优化的,那性能优化就应该一把梭子吗?仍是要符合一些规范和原则呢?安全

因此,在开始以前(MySQL 优化),我们先来聊聊性能优化的一些原则。性能优化

性能优化原则和分类

性能优化通常能够分为:服务器

主动优化

被动优化

所谓的主动优化是指不须要外力的推进而自发进行的一种行为,好比当服务没有明显的卡顿、宕机或者硬件指标异常的状况下,自我出发去优化的行为,就能够称之为主动优化。微信

而被动优化恰好与主动优化相反,它是指在发现了服务器卡顿、服务异常或者物理指标异常的状况下,才去优化的这种行为。

性能优化原则

不管是主动优化仍是被动优化都要符合如下性能优化的原则:

优化不能改变服务运行的逻辑,要保证服务的

正确性;

优化的过程和结果都要保证服务的

安全性;

要保证服务的

稳定性,不能为了追求性能牺牲程序的稳定性。好比不能为了提升 Redis 的运行速度,而关闭持久化的功能,由于这样在 Redis 服务器重启或者掉电以后会丢失存储的数据。

以上原则看似都是些废话,但却给了咱们一个启发,那就是咱们性能优化手段应该是:预防性能问题为主+被动优化为辅。

也就是说,咱们应该以预防性能问题为主,在开发阶段尽量的规避性能问题,而在正常状况下,应尽可能避免主动优化,以防止未知的风险(除非是为了 KPI,或者是闲的没事),尤为对生产环境而言更是如此,最后才是考虑被动优化。

PS:当遇到性能缓慢降低、或硬件指标缓慢增长的状况,现在天内存的占用率是 50%,明天是 70%,后天是 90% ,而且丝毫没有收回的迹象时,咱们应该提前发现并处理此类问题(这种状况也属于被动优化的一种)。

MySQL 被动性能优化

因此咱们本文会重点介绍 MySQL 被动性能优化的知识,根据被动性能优化的知识,你就能够获得预防性能问题发生的一些方法,从而规避 MySQL 的性能问题。

本文咱们会从问题入手,而后考虑这个问题产生的缘由以及相应的优化方案。咱们在实际开发中,一般会遇到如下 3 个问题:

单条 SQL 运行慢;

部分 SQL 运行慢;

整个 SQL 运行慢。

问题 1:单条 SQL 运行慢

问题分析

形成单条 SQL 运行比较慢的常见缘由有如下两个:

未正常建立或使用索引;

表中数据量太大。

解决方案 1:建立并正确使用索引

索引是一种能帮助 MySQL 提升查询效率的主要手段,所以通常状况下咱们遇到的单条 SQL 性能问题,一般都是因为未建立或为正确使用索引而致使的,因此在遇到单条 SQL 运行比较慢的状况下,你首先要作的就是检查此表的索引是否正常建立。

若是表的索引已经建立了,接下来就要检查一下此 SQL 语句是否正常触发了索引查询,若是发生如下状况那么 MySQL 将不能正常的使用索引:

在 where 子句中使用 != 或者 <> 操做符,查询引用会放弃索引而进行全表扫描;

不能使用前导模糊查询,也就是 '%XX' 或 '%XX%',因为前导模糊不能利用索引的顺序,必须一个个去找,看是否知足条件,这样会致使全索引扫描或者全表扫描;

若是条件中有 or 即便其中有条件带索引也不会正常使用索引,要想使用 or 又想让索引生效,只能将 or 条件中的每一个列都加上索引才能正常使用;

在 where 子句中对字段进行表达式操做。

所以你要尽可能避免以上状况,除了正常使用索引以外,咱们也能够使用如下技巧来优化索引的查询速度:

尽可能使用主键查询,而非其余索引,由于主键查询不会触发回表查询;

查询语句尽量简单,大语句拆小语句,减小锁时间;

尽可能使用数字型字段,若只含数值信息的字段尽可能不要设计为字符型;

用 exists 替代 in 查询;

避免在索引列上使用 is null 和 is not null。

回表查询:普通索引查询到主键索引后,回到主键索引树搜索的过程,咱们称为回表查询。

解决方案 2:数据拆分

当表中数据量太大时 SQL 的查询会比较慢,你能够考虑拆分表,让每张表的数据量变小,从而提升查询效率。

1.垂直拆分

指的是将表进行拆分,把一张列比较多的表拆分为多张表。好比,用户表中一些字段常常被访问,将这些字段放在一张表中,另一些不经常使用的字段放在另外一张表中,插入数据时,使用事务确保两张表的数据一致性。垂直拆分的原则:

把不经常使用的字段单独放在一张表;

把 text,blob 等大字段拆分出来放在附表中;

常常组合查询的列放在一张表中。

2.水平拆分

指的是将数据表行进行拆分,表的行数超过200万行时,就会变慢,这时能够把一张的表的数据拆成多张表来存放。一般状况下,咱们使用取模的方式来进行表的拆分,好比,一张有 400W 的用户表 users,为提升其查询效率咱们把其分红 4 张表 users1,users2,users3,users4,而后经过用户 ID 取模的方法,同时查询、更新、删除也是经过取模的方法来操做。

表的其余优化方案:

使用能够存下数据最小的数据类型;

使用简单的数据类型,int 要比 varchar 类型在 MySQL 处理简单;

尽可能使用 tinyint、smallint、mediumint 做为整数类型而非 int;

尽量使用 not null 定义字段,由于 null 占用 4 字节空间;

尽可能少用 text 类型,非用不可时最好考虑分表;

尽可能使用 timestamp,而非 datetime;

单表不要有太多字段,建议在 20 个字段之内。

问题 2:部分 SQL 运行慢

问题分析

部分 SQL 运行比较慢,咱们首先要作的就是先定位出这些 SQL,而后再看这些 SQL 是否正确建立并使用索引。也就是说,咱们先要使用慢查询工具定位出具体的 SQL,而后再使用问题 1 的解决方案处理慢 SQL。

解决方案:慢查询分析

MySQL 中自带了慢查询日志的功能,开启它就能够用来记录在 MySQL 中响应时间超过阀值的语句,具体指运行时间超过 long_query_time 值的 SQL,则会被记录到慢查询日志中。long_query_time 的默认值为 10,意思是运行 10S 以上的语句。默认状况下,MySQL 数据库并不启动慢查询日志,须要咱们手动来设置这个参数,若是不是调优须要的话,通常不建议启动该参数,由于开启慢查询日志会给 MySQL 服务器带来必定的性能影响。慢查询日志支持将日志记录写入文件,也支持将日志记录写入数据库表。使用 mysql> show variables like '%slow_query_log%'; 来查询慢查询日志是否开启,执行效果以下图所示:

slow_query_log 的值为 OFF 时,表示未开启慢查询日志。

开启慢查询日志

开启慢查询日志,可使用以下 MySQL 命令:

mysql> set global slow_query_log=1

不过这种设置方式,只对当前数据库生效,若是 MySQL 重启也会失效,若是要永久生效,就必须修改 MySQL 的配置文件 my.cnf,配置以下:

slow_query_log =1 slow_query_log_file=/tmp/mysql_slow.log

当你开启慢查询日志以后,全部的慢查询 SQL 都会被记录在 slow_query_log_file 参数配置的文件内,默认是 /tmp/mysql_slow.log 文件,此时咱们就能够打开日志查询到全部慢 SQL 进行逐个优化。

问题 3:整个 SQL 运行慢

问题分析

当出现整个 SQL 都运行比较慢就说明目前数据库的承载能力已经到了峰值,所以咱们须要使用一些数据库的扩展手段来缓解 MySQL 服务器了。

解决方案:读写分离

通常状况下对数据库而言都是“读多写少”,换言之,数据库的压力多数是由于大量的读取数据的操做形成的,咱们能够采用数据库集群的方案,使用一个库做为主库,负责写入数据;其余库为从库,负责读取数据。这样能够缓解对数据库的访问压力。

MySQL 常见的读写分离方案有如下两种:

1.应用层解决方案

能够经过应用层对数据源作路由来实现读写分离,好比,使用 SpringMVC + MyBatis,能够将 SQL 路由交给 Spring,经过 AOP 或者 Annotation 由代码显示的控制数据源。优势:路由策略的扩展性和可控性较强。缺点:须要在 Spring 中添加耦合控制代码。

2.中间件解决方案

经过 MySQL 的中间件作主从集群,好比:Mysql Proxy、Amoeba、Atlas 等中间件都能符合需求。优势:与应用层解耦。缺点:增长一个服务维护的风险点,性能及稳定性待测试,须要支持代码强制主从和事务。

扩展知识:SQL 语句分析

在 MySQL 中咱们可使用 explain 命令来分析 SQL 的执行状况,好比:

explain select * from t where id=5;

以下图所示:

其中:

id — 选择标识符,id 越大优先级越高,越先被执行;

select_type — 表示查询的类型;

table — 输出结果集的表;

partitions — 匹配的分区;

type — 表示表的链接类型;

possible_keys — 表示查询时,可能使用的索引;

key — 表示实际使用的索引;

key_len — 索引字段的长度;

ref—  列与索引的比较;

rows — 大概估算的行数;

filtered — 按表条件过滤的行百分比;

Extra — 执行状况的描述和说明。

其中最重要的就是 type 字段,type 值类型以下:

all — 扫描全表数据;

index — 遍历索引;

range — 索引范围查找;

index_subquery — 在子查询中使用 ref;

unique_subquery — 在子查询中使用 eq_ref;

ref_or_null — 对 null 进行索引的优化的 ref;

fulltext — 使用全文索引;

ref — 使用非惟一索引查找数据;

eq_ref — 在 join 查询中使用主键或惟一索引关联;

const — 将一个主键放置到 where 后面做为条件查询, MySQL 优化器就能把此次查询优化转化为一个常量,如何转化以及什么时候转化,这个取决于优化器,这个比 eq_ref 效率高一点。

总结

本文咱们介绍了 MySQL 性能优化的原则和分类,MySQL 的性能优化可分为:主动优化和被动优化,但不管何种优化都要保证服务的正确性、安全性和稳定性。它带给咱们的启发是应该采用:预防 + 被动优化的方案来确保 MySQL 服务器的稳定性,而被动优化常见的问题是:

单条 SQL 运行慢;

部分 SQL 运行慢;

整个 SQL 运行慢。

所以咱们给出了每种被动优化方案的问题分析和解决方案,但愿本文能够帮助到你。

MySQL的主动优化和被动优化_不要一把梭了,这才是SQL优化的正确姿式!|原创干货...相关推荐

  1. mysql sql语句优化面试_面试不要一把梭了,这才是SQL优化的正确姿势

    全文内容预览: 所以,在开始之前(MySQL 优化),咱们先来聊聊性能优化的一些原则. 性能优化原则和分类 性能优化一般可以分为:主动优化 被动优化 所谓的主动优化是指不需要外力的推动而自发进行的一种 ...

  2. sql 拼接int类型的字段_这才是SQL优化的正确姿势!

    文末扫海报二维码领[30份Excel可视化数据看板] 磊哥 | 作者 Java中文社群 | 来源 全文内容预览: 当然,本篇是关于性能优化的,那性能优化就应该一把梭子吗?还是要符合一些规范和原则呢? ...

  3. 不要一把梭了,这才是SQL优化的正确姿势!

    问题 1:单条 SQL 运行慢 问题分析 造成单条 SQL 运行比较慢的常见原因有以下两个: 未正常创建或使用索引: 表中数据量太大. 解决方案 1:创建并正确使用索引 索引是一种能帮助 MySQL ...

  4. 不要一把梭了,这才是SQL优化的正确姿势

    全文内容预览: 性能优化原则和分类 性能优化一般可以分为: 主动优化 被动优化 所谓的主动优化是指不需要外力的推动而自发进行的一种行为,比如当服务没有明显的卡顿.宕机或者硬件指标异常的情况下,自我出发 ...

  5. 凸优化 机器学习 深度学习_我应该在机器学习项目中使用哪个优化程序

    凸优化 机器学习 深度学习 This article provides a summary of popular optimizers used in computer vision, natural ...

  6. java局部变量的描述正确的是_【Java入门课|这才是Java局部变量的正确使用方法,你真的会用这些吗】- 环球网校...

    [摘要]作为一门面向对象编程语言,Java吸收了C++语言的优点,也展现了其强大的一面,我们能在各个地方看到其功能强大和简单易用的两个特征,当然,也吸引了很多程序员的注意力,所以就有人想了解Java的 ...

  7. 苹果手机太卡怎么清理_苹果手机卡顿,这才是清理缓存的正确方法,瞬间流畅好几倍...

    苹果手机用久了卡的比较厉害,下面就来教大家如何正确清理苹果手机的缓存,让老版本的苹果手机更流畅,这个技巧只针对于一些老版本带home键的苹果手机,下面我们用iPhone8 Plus作为演示. 1.首先 ...

  8. 苹果手机怎么清理缓存_苹果手机卡顿,这才是清理缓存的正确方法,瞬间流畅好几倍...

    苹果手机用久了卡的比较厉害,下面就来教大家如何正确清理苹果手机的缓存,让老版本的苹果手机更流畅,这个技巧只针对于一些老版本带home键的苹果手机,下面我们用iPhone8 Plus作为演示. 1.首先 ...

  9. 谈谈mysql优化_浅谈MySQL SQL优化

    本文首发于个人微信公众号<andyqian>,期待你的关注 前言 有好几天没有写文章了,实在不好意思.之前就有朋友希望我写写MySQL优化的文章.我迟迟没有动笔,主要是因为,SQL优化这个 ...

最新文章

  1. Ubuntu开机自启动 读取.bashrc
  2. SEO之网站页面优化策略
  3. RFC 4303--ESP
  4. 在什么时候才会用到fireEvent方法呢?
  5. 不断提升自己创造溢价的能力
  6. C++ Primer 5th笔记(chap 18 大型程序工具)多重继承下的类作用域
  7. 介绍一个Excel批量处理软件
  8. 青海省多地日降水量突破历史极值
  9. SQL学习之SELECT子句顺序
  10. 安卓依然是华为手机首选,鸿蒙系统或许不用于手机
  11. 慕课网 饿了么 vue2.0 项目
  12. npm install 报错(npm ERR! errno: -4048, npm ERR! code: ‘EPERM‘, npm ERR! syscall: ‘unlink‘,)
  13. html radio 默认图片替换_用纯CSS改变html radio/checkbox默认背景颜色样式
  14. openstack创建的实例不能使用ssh登录
  15. lambda函数 python菜鸟教程-Python3 函数
  16. FireMonkey Control的Paint顺序
  17. stm32模块化编程
  18. 用javascript为页面添加蒙版效果和弹出层
  19. 阿里云轻量应用服务器的租赁与使用
  20. 通过css为类生成器给文本字体加上书名号,

热门文章

  1. 2021最新 SpringBoot面试题精选(附刷题小程序)
  2. 推荐几个非常实用的测试工具
  3. C++ 多项式计算器
  4. python绘制花色分形树
  5. centos卸载软件及其依赖方法
  6. Java 字符串长度不足左右补0
  7. 【经典案例】 | 多元线性回归模型预测房价(附Python代码与数据)
  8. ios点击推送闪退_科普:苹果手机闪退怎么办?
  9. Aspose.CAD for .NET 22.11.0 cRACK
  10. 独热码(One-Hot编码)