MySQL优化

文章目录

    • 使用须知
    • 特点
      • 1、CPU
      • 2、内存
      • 3、磁盘
    • 4个维度优化
      • 硬件优化
      • 配置参数优化
      • linux层面对MySQL优化
      • 表设计及其他优化

使用须知

  • 不要错误得把它当做一个文件存储,如图片、附件等放入MySQL中,容易导致表空间庞大,磁盘I/O的读写能性能很差
  • 不要把MySQL数据库当成一个计算器,在其中进行大量复杂的运算
  • 不要把它当成一个全文检索工具,单纯地把MySQL当成一个可以处理并发事务,保证数据一致性的数据库就可以了

特点

从CPU、内存、磁盘三个方面阐述

1、CPU

MySQL5.1版本之前的多核支持能力很差,随着后期版本的升级,用到的CPU核数越来越多,5.6版本已经可以用到64核,建议定期升级MySQL线上的版本到最新的稳定版本

当每个连接进入数据库是,MySQL都会创建一个线程来响应此连接的请求。每个SQL语句只能用一个CPU核心,如果此SQL语句执行很缓慢,就容易出现锁等待、排队等现象。所以设计的业务逻辑不要过于复杂,避免写那种很多表的连接的SQL语句,尽量让SQL语句快速执行成功,在项目初期设计表时,数据类型越简单越好

2、内存

MySQL内存组成和Oracle类似,可以分为SGA(系统全局区)和PGA(程序缓存区)。每个连接会话连到数据库时,都会为其分配内存,分配的内存大小一定控制好,不宜过大,防止当业务高峰,连接数过高时,有可能出现OOM现象(内存溢出)。

相比Oracle的内存管理机制,MySQL的内存管理还是很简单。在InnoDB存储引擎中实现了自己的内存池系统和内存堆分配系统,在InnoDB的内存管理系统中,大致分为基础的内存块分配管理、内存伙伴分配器和内存堆分配器三个部分。InnoDB定义和实现内存池的主要目的是提供内存的使用率和效率,防止内存碎片和内存分配跟踪和调试。内存的主要作用就是缓存热点数据,尽量保证所有的读取操作都在内存中完成,避免产生过多的物理I/O。

在业务高峰期,高并发的环境下,我们可以适当增加物理内存大小,来提高数据库的并发性能。

innodb_buffer_pool作用是缓存InnoDB表的数据、索引、插入缓冲、数据字典等信息。如果是单实例,且数据库中绝大部分是InnoDB存储引擎表,它的大小可以考虑设置为物理内存的50%-80%。

query cache 建议关闭,可以选择Redis、Memcache或MangoDB来缓存热点数据层

3、磁盘

MySQL的binlog文件、存储引擎文件undo和redo都是顺序写入的方式,数据文件是伴随顺序写和随机写一起。

OLTP这类业务系统都是以随机I/O为主,可以通过增加内存来提升数据库读写性能

4个维度优化

优化SQL,需要从4个维度方面优化,从下到上为 硬件设备优化、MySQL数据库、Linux操作系统、表设计

硬件优化

影响数据库最大的性能问题就是磁盘I/O,为了提升数据库IOPS性能,可以使用SSD或PCIE-SSD高速磁盘设备,至少可以获得上百倍或者上万倍的IOPS系能提升

当数据库系统TPS过高或者业务量叫较高时,一定要配置阵列卡(RAID 1+ 0),而且阵列卡一直要配备cache模块,cache模块还要配置BBU模块来提供持续的电量。在选择阵列卡的cache策略是,为了提高I/O写数据性能,建议设置为Write Back(WB),这种策略是将数据先写到cache中,然后通过阵列卡控制刷回到磁盘里面

在服务器BIOS层面也可以对MySQL数据库的优化进行一些配置参数的设置。CPU建议采用最大性能模式,选择performance per watt optimized来充分发挥CPU的最大功耗性能,同时建议关闭C1EC stats 这类节能选项,因为当负载增加,或者访问量变大时,有可能造成数据库响应不了太大的请求,从而出现数据库性能变慢、卡住的现象,甚至可能MySQL服务宕机

内存方面也要选择最大系能模式maximum performance,尽量在BIOS里面禁掉NUMA功能,将Node Interleaving设置为Enabled模式,让内存在多个CPU节点之间进行循环使用,这样可以更好地利用内存

配置参数优化

  • innodb_buffer_pool 如果是单实例且绝大数是InnoDB引擎表,则可以设置为物理内存50%~80%左右
  • innodb_flush_log_at_trx_commitsync_binlog分别是redo log刷新和bin log 刷新的参数。如果要求数据不能丢失,建议把这两个参数都设置为1,可以保证主从架构中数据的一致性。想保证其强一致性,可以考虑增强半同步功能
  • innodb_max_dirty_pages_pct 指脏页占innodb buffer pool的比例。 当比例到达所设置的值,触发脏页刷盘,建议25%-50%
  • innodb_io_capacityInnoDB后台进程最大的I/O性能指标,影响刷新脏页和插入缓冲的数量。默认设置200,在高转速磁盘下,可以适当提高,SSD建议 5000-2000,PCIE-SSD 建议 50000左右
  • innodb_data_file_path = ibdata1:1G:autoextend
  • long_query_time 记录慢查询sql时间,建议0.1~0.5,后续优化sql
  • binlog_format binlog 的记录格式 建议 row格式
  • interactive_timeout,wait_timeout 分别代表交互等待时间和非交互等待时间 建议 300~500s
  • max_connections 最大连接数 超过 容易产生OOM,kill掉MySQL服务
  • innodb_log_file_size redo log的值 , 值太大,当实例恢复时,会消耗大量时间,值太小会造成日志切换频繁
  • gerenal log 全量日志建议关闭 ,否则该日志文件会越来越大,造成磁盘空间的紧张,MySQL性能下降

linux层面对MySQL优化

  • IO调度建议选 deadline或noop模式,不要选cfg模式

cat /sys/block/sda/queue/scheduler

  • 文件系统 建议选择xfs,其次ext4

  • 内核参数

    vm.swapiness 使用swap的意向,可以在1~10范围内取值

    查看 cat /proc/sys/vm/swappiness/etc/sysctl.conf

    vm.swappiness=0 禁用swap,可能出现OOM现象

    vm.swappiness=1 尽量不使用swap

    vm.swappiness=60 默认值

    vm.swappiness=100 积极得使用swap,很影响性能

    vm.dirty_background_ratio 当文件系统缓存脏页数量到达系统内存的百分比多少时,就会触发pdflush/flush/kdmflush 等后台回写进程运行,将一定的缓存的脏页异步刷入磁盘,建议不超过10

    vm.dirt_ratio 指定了当文件系统脏页数量达到系统内存百分比多少时,系统不得不开始处理缓存脏页

表设计及其他优化

  • (1) 在创建业务表时,库名、表名、字段名必须使用小写字母,采用_分割
  • (2) MySQL数据库中,通过lower_case_table_name 区分表的大小写,默认为0,代表大小写敏感,如果是1,代码大小写不敏感,以小写存储。为字段选取数据类型时,秉承简单、够用的原则。表中的字段和索引数量不宜过多,要保证SQL语句查询的高效性,快速执行完,避免出现阻塞、排队现象
  • (3) 表的存储引擎选择InnoDB
  • (4) 要显式地为表创建一个使用自增列INT或BIGINT类型的主键,可以保证写入顺序是自增的,和B+tree叶子节点分裂顺序一直。写入更加高效,TPS性能会更高,存储效率也是最高的
  • (5) 金钱、日期时间、IPv4尽量使用int存储
  • (6) text和blob这种存大量文字或者图片的大数据类型,建议不要与业务表放在一起
  • (7) 用select查询表示只需要获取必要的字段,避免使用 select * 。 可以减少网络带宽的消耗,还有可能利用到覆盖索引
  • (8) 很长的字符串可以创建前缀索引

你可能感兴趣的:(mysql)