MySQL 的优化方案总结

MySQL 的常见的优化方案

       性能优化(Optimize)指的是在保证系统正确性的前提下,可以更快速响应请求的一种手段。并且有些性能问题,好比慢查询等,若是积累到必定的程度或者是遇到急速上升的并发请求以后,会致使严重的后果,轻则形成服务繁忙,重则致使应用不可用。它对咱们来讲就像一颗即将被引爆的定时炸弹同样,时刻威胁着咱们。所以在上线项目以前须要严格的把关,以确保 MySQL 可以以最优的状态进行运行。mysql

MySQL 的优化方案有哪些?

       MySQL 数据库常见的优化手段分为三个层面:SQL 和索引优化、数据库结构优化、系统硬件优化,然而每一个大的方向中又包含多个小的优化点,下面咱们具体来看看。sql

优化注意事项:

  • 依据数据而不是凭空猜想
  • 忌过早优化
  • 忌过分优化
  • 深刻理解业务
  • 性能优化是持久战
  • 选择合适的衡量指标、测试用例、测试环境

优化目标

  • 减小 IO 次数 IO永远是数据库最容易瓶颈的地方,这是由数据库的职责所决定的,大部分数据库操做中超过90%的时间都是 IO 操做所占用的,减小 IO 次数是 SQL 优化中须要第一优先考虑,固然,也是收效最明显的优化手段。
  • 下降 CPU 计算 除了 IO 瓶颈以外,SQL优化中须要考虑的就是 CPU 运算量的优化了。order by, group by,distinct … 都是消耗 CPU 的大户(这些操做基本上都是 CPU 处理内存中的数据比较运算)。当咱们的 IO 优化作到必定阶段以后,下降 CPU 计算也就成为了咱们 SQL 优化的重要目标

优化方案一: SQL 和索引优化

  • 使用正确的索引
           索引是数据库中最重要的概念之一,也是提升数据库性能最有效的手段之一,它的诞生自己就是为了提升数据查询效率的,就像字典的目录同样,经过目录能够很快找到相关的内容。咱们应该尽量的使用主键查询,而非其余索引查询,由于主键查询不会触发回表查询,所以节省了一部分时间,变相的提升了查询的性能。数据库

    索引类型普通索引、主键索引、惟一索引、组合索引、全文索引
           假如咱们没有添加索引,那么在查询时就会触发全表扫描,所以查询的数据就会不少,而且查询效率会很低,为了提升查询的性能,咱们就须要给最常使用的查询字段上,添加相应的索引,这样才能提升查询的性能数组

  • sql书写时的注意缓存

    • 在 MySQL 5.0 以前的版本要尽可能避免使用 or 查询,可使用 union 或者子查询来替代,由于早期的 MySQL 版本使用 or 查询可能会致使索引失效,在 MySQL 5.0 以后的版本中引入了索引合并,简单来讲就是把多条件查询,好比 or 或 and 查询的结果集进行合并交集或并集的功能,所以就不会致使索引失效的问题了。若是限制条件中其余字段没有索引,尽可能少用or。
    • 避免在 where 查询条件中使用 != 或者 <> 操做符,由于这些操做符会致使查询引擎放弃索引而进行全表扫描。
    • 适当使用前缀索引,MySQL 是支持前缀索引的,也就是说咱们能够定义字符串的一部分来做为索引。咱们知道索引越长占用的磁盘空间就越大,那么在相同数据页中能放下的索引值也就越少,这就意味着搜索索引须要的查询时间也就越长,进而查询的效率就会下降,因此咱们能够适当的选择使用前缀索引,以减小空间的占用和提升查询效率。
    • 要尽可能避免使用 select *,而是查询须要的字段,这样能够提高速度,以及减小网络传输的带宽压力。
    • 关于JOIN优化,尽可能使用 Join 语句来替代子查询,由于子查询是嵌套查询,而嵌套查询会新建立一张临时表,而临时表的建立与销毁会占用必定的系统资源以及花费必定的时间,但 Join 语句并不会建立临时表,所以性能会更高。
    • 咱们要尽可能使用小表驱动大表的方式进行查询,也就是若是 B 表的数据小于 A 表的数据,那执行的顺序就是先查 B 表再查 A 表。
    • 不要在列字段上进行算术运算或其余表达式运算,不然可能会致使查询引擎没法正确使用索引,从而影响了查询的效率。
    • 增长冗余字段能够减小大量的连表查询,由于多张表的连表查询性能很低,全部能够适当的增长冗余字段,以减小多张表的关联查询,这是以空间换时间的优化策略。
    • 避免类型转换,这里所说的“类型转换”是指 where 子句中出现 column 字段的类型和传入的参数类型不一致的时候发生的类型转换。
    • 尽可能用 union all 代替 union,union 和 union all 的差别主要是前者须要将两个(或者多个)结果集合并后再进行惟一性过滤操做,这就会涉及到排序,增长大量的 CPU 运算,加大资源消耗及延迟。因此当咱们能够确认不可能出现重复结果集或者不在意重复结果集的时候,尽可能使用 union all 而不是 union。
    • 尽可能少排序 order by,排序操做会消耗较多的 CPU 资源,因此减小排序能够在缓存命中率高等 IO 能力足够的场景下会较大影响 SQL 的响应时间。若是排序字段没有用到索引,就尽可能少排序。
    • SQL语句中IN包含的值不该过多,MySQL对于IN作了相应的优化,即将IN中的常量所有存储在一个数组里面,并且这个数组是排好序的。可是若是数值较多,产生的消耗也是比较大的。
    • 当只须要一条数据的时候,使用limit 1,这是为了使EXPLAIN中type列达到const类型。
    • 区分in和exists, not in和not exists。
    • 使用合理的分页方式以提升分页的效率。
    • 分段查询
    • 避免在 where 子句中对字段进行 null 值判断
    • 不建议使用%前缀模糊查询,若是使用%前缀来模糊查询,建议使用全文索引。
    • 对于联合索引来讲,要遵照最左前缀法则。好比:组合索引(a,b,c)三列,咱们可使用(a)、(a,b)、(a,c)、(b、c)、(a,b,c)可是不能以(b,a)、(c,a)、(c,b)等组合使用不然致使索引失效。
    • 必要时可使用force index来强制查询走某个索引。

以上这些优化方案咱们均可以经过EXPLAIN方式来验证。性能优化

在这里插入图片描述
EXPLAIN各个字段详介绍:
在这里插入图片描述
type字段值以下:
在这里插入图片描述

优化方案二:数据库结构优化

最小数据长度服务器

       通常说来数据库的表越小,那么它的查询速度就越快,所以为了提升表的效率,应该将表的字段设置的尽量小,好比身份证号,能够设置为 char(18) 就不要设置为 varchar(18)。网络

使用最简单数据类型并发

       能使用 int 类型就不要使用 varchar 类型,由于 int 类型比 varchar 类型的查询效率更高。性能

尽可能少定义 text 类型

       text 类型的查询效率很低,若是必需要使用 text 定义字段,能够把此字段分离成子表,须要查询此字段时使用联合查询,这样能够提升主表的查询效率。

选择合适的存储引擎

       存储引擎类型:MyISAM、InnoDB、MEMORY、MERGE、TokuDB、CSV、Archive

       MyISAM:若是应用是以读操做和插入操做为主,只有不多的更新和删除操做,而且对事务的完整性、并发性要求不是很高,那么选择该存储引擎是很是合适的。MyISAM是在Web、数据仓库和其余应用环境下最常使用的存储引擎之一。

        InnoDB:用于事务处理应用程序,支持外键。若是应用程序对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操做除了插入和查询外,还包括不少的更新、删除操做,那么InnoDB存储引擎是比较合适的选择。InnoDB存储引擎除了有效地下降因为删除和更新致使地锁定,还能够确保事务地完整提交(Commit)和回滚(Rollback),对于相似计费系统或者财务系统等对数据准确性要求较高地系统,InnoDB都是合适地选择。

       MEMORY:将全部数据保存在RAM中,在须要快速定位记录和其余相似数据的环境下,可提供极快的访问。MEMORY的缺陷是对表的大小有限制,太大的表没法缓存在内存中,其次是要确保表的数据能够恢复,数据库异常终止后表中的数据是能够恢复的。MEMORY表一般用于更新不太频繁的小表,用以快速访问结果。

       MERGE:用于将一系列等同地MyISAM表以逻辑方式组合在一块儿,并做为一个对象引用它们,MERGE表地优势在于能够突破对单个MyISAM表大小的限制,而且经过将不一样的表分布在多个磁盘上,能够有效地改善MERGE表的访问效率,这对于诸如数据仓库等VLDB环境十分适合。属于第三方存储引擎 ,高写性能高压缩率,支持事务处理的MySQL和MariaDB的存储引擎,支持大多数在线DDL操做。

       TokuDB:使用Fractal树索引保证高效的插入性能;优秀的压缩特性,比InnoDB高近10倍;Hot Schema Changes特性支持在线建立索引和添加、删除属性列等DDL操做。使用Bulk Loader达到快速加载大量数据;提供了主从延迟消除技术;支持ACID和MVCC。

三种常见的存储引擎对比:

在这里插入图片描述
适当分表、分库策略

       分表和分库方案也是咱们常常说的垂直分隔(分表)和水平分隔(分库)。

       分表是指当一张表中的字段更多时,能够尝试将一张大表拆分为多张子表,把使用比较高频的主信息放入主表中,其余的放入子表,这样咱们大部分查询只须要查询字段更少的主表就能够完成了,从而有效的提升了查询的效率。

       分库是指将一个数据库分为多个数据库。好比咱们把一个数据库拆分为了多个数据库,一个主数据库用于写入和修改数据,其余的用于同步主数据并提供给客户端查询,这样就把一个库的读和写的压力,分摊给了多个库,从而提升了数据库总体的运行效率。

优化方案三: 系统硬件优化

MySQL 对硬件的要求主要体如今三个方面:磁盘、网络和内存。

磁盘

       磁盘寻道能力(磁盘I/O),以目前高转速SCSI硬盘(7200转/秒)为例,这种硬盘理论上每秒寻道7200次,这是物理特性决定的,没有办法改变;磁盘应该尽可能使用有高性能读写能力的磁盘,好比固态硬盘,这样就能够减小 I/O 运行的时间,从而提升了 MySQL 总体的运行效率。
       磁盘也能够尽可能使用多个小磁盘而不是一个大磁盘,由于磁盘的转速是固定的,有多个小磁盘就至关于拥有多个并行运行的磁盘同样。

网络

       保证网络宽带的通畅(低延迟)以及够大的网络带宽是 MySQL 正常运行的基本条件,若是条件容许的话也能够设置多个网卡,以提升网络高峰期 MySQL 服务器的运行效率。
       DNS配置 尽可能使用skip-name-resolve来减小因解析带来的没必要要麻烦。
       检查网络的ping 丢包率。
       经过优化/etc/sysctl.cnf 中的网络参数,提高性能。

内存

       MySQL 服务器的内存越大,那么存储和缓存的信息也就越多,而内存的性能是很是高的,从而提升了整个 MySQL 的运行效率。

知识扩展

       慢查询慢查询一般的排查手段是先使用慢查询日志功能,查询出比较慢的 SQL 语句,而后再经过 explain 来查询 SQL 语句的执行计划,最后分析并定位出问题的根源,再进行处理(上文中有介绍到)。

       慢查询日志指的是在 MySQL 中能够经过配置来开启慢查询日志的记录功能,超过 long_query_time 值的 SQL 将会被记录在日志中。咱们能够经过设置“slow_query_log=1”来开启慢查询,它的开启方式有两种:

       经过 MySQL 命令行的模式进行开启,只须要执行“set global slow_query_log=1”便可,然而这种配置模式再重启 MySQL 服务以后就会失效;        另外一种方式可经过修改 MySQL 配置文件的方式进行开启,咱们须要配置 my.cnf中的“slow_query_log=1”便可,而且能够经过设置“slow_query_log_file=/tmp/mysql_slow.log”来配置慢查询日志的存储目录,但这种方式配置完成以后须要重启 MySQL 服务器才可生效。
       须要注意的是,在开启慢日志功能以后,会对 MySQL 的性能形成必定的影响,所以在生产环境中要慎用此功能。

====================== END =========================

相关文章
相关标签/搜索