照片视频制作软件,网站seo排名培训,有的网站显示正在建设中,网页制作与设计实验报告这是我的第 83 篇原创文章作者 | 王磊来源 | Java中文社群#xff08;ID#xff1a;javacn666#xff09;转载请联系授权#xff08;微信ID#xff1a;GG_Stone#xff09;年少不知优化苦#xff0c;遇坑方知优化难。——村口王大爷全文内容预览#xff1a;我之前有很多… 这是我的第 83 篇原创文章作者 | 王磊来源 | Java中文社群IDjavacn666转载请联系授权微信IDGG_Stone年少不知优化苦遇坑方知优化难。——村口王大爷全文内容预览我之前有很多文章都在讲性能优化的问题比如下面这些《switch 的性能提升了 3 倍我只用了这一招》《String性能提升10倍的几个方法(源码原理分析)》《局部变量竟然比全局变量快 5 倍》《池化技术到达有多牛看了线程和线程池的对比吓我一跳》《链表竟然比数组慢了1000多倍(动图性能评测)》《HashMap 的 7 种遍历方式与性能分析》更多性能优化文章当然本篇也是关于性能优化的那性能优化就应该一把梭子吗还是要符合一些规范和原则呢所以在开始之前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.垂直拆分指的是将表进行拆分把一张列比较多的表拆分为多张表。比如用户表中一些字段经常被访问将这些字段放在一张表中另外一些不常用的字段放在另一张表中插入数据时使用事务确保两张表的数据一致性。垂直拆分的原则把不常用的字段单独放在一张表把 textblob 等大字段拆分出来放在附表中经常组合查询的列放在一张表中。2.水平拆分指的是将数据表行进行拆分表的行数超过200万行时就会变慢这时可以把一张的表的数据拆成多张表来存放。通常情况下我们使用取模的方式来进行表的拆分比如一张有 400W 的用户表 users为提高其查询效率我们把其分成 4 张表 users1users2users3users4然后通过用户 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_log1不过这种设置方式只对当前数据库生效如果 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 id5;如下图所示其中id — 选择标识符id 越大优先级越高越先被执行select_type — 表示查询的类型table — 输出结果集的表partitions — 匹配的分区type — 表示表的连接类型possible_keys — 表示查询时可能使用的索引key — 表示实际使用的索引key_len — 索引字段的长度ref— 列与索引的比较rows — 大概估算的行数filtered — 按表条件过滤的行百分比Extra — 执行情况的描述和说明。其中最重要的就是 type 字段type 值类型如下all — 扫描全表数据index — 遍历索引range — 索引范围查找index_subquery — 在子查询中使用 refunique_subquery — 在子查询中使用 eq_refref_or_null — 对 null 进行索引的优化的 reffulltext — 使用全文索引ref — 使用非唯一索引查找数据eq_ref — 在 join 查询中使用主键或唯一索引关联const — 将一个主键放置到 where 后面作为条件查询 MySQL 优化器就能把这次查询优化转化为一个常量如何转化以及何时转化这个取决于优化器这个比 eq_ref 效率高一点。总结本文我们介绍了 MySQL 性能优化的原则和分类MySQL 的性能优化可分为主动优化和被动优化但无论何种优化都要保证服务的正确性、安全性和稳定性。它带给我们的启发是应该采用预防 被动优化的方案来确保 MySQL 服务器的稳定性而被动优化常见的问题是单条 SQL 运行慢部分 SQL 运行慢整个 SQL 运行慢。因此我们给出了每种被动优化方案的问题分析和解决方案希望本文可以帮助到你。 最后的话原创不易都看到这了点个「赞」再走呗这是对我最大的支持与鼓励谢谢你往期推荐
阿里《Java开发手册》最新嵩山版发布池化技术到达有多牛看了线程和线程池的对比吓我一跳关注下方二维码每一天都有干货