MySQL——数据库调优

46 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情

1、调优的目标

尽可能节省系统资源,以便系统可以提供更大负荷的服务,吞吐量更大。

合理的结构设计和参数调整,以提高用户操作的响应速度。

减少系统的瓶颈,提高数据库整体的性能,减少 I/O 次数,降低 CPU 计算。

2、确定调优的目标

可以根据以下几点确定调优的目标:

  • 用户反馈:用户的反馈是最直接的,而且有些问题往往是用户第一时间发现的
  • 日志分析:查看数据库日志和操作系统日志找出异常情况
  • 服务器资源使用监控:通过CPU、内存和I/O等使用情况,查看服务器的性能使用
  • 数据库内部状况监控:MySQL有个状态变量 Threads_running,记录了当前并发执行stmt/command的数量,执行前加1执行后减1;当Threads_running 和 CPU load(CPU负载)值很接近时,表示系统基本快跑满了,需要调优

3、调优的维度和步骤

第一步:选择合适的DBMS

DBMS的选择关系到后面的整个设计过程。

第二步:优化表设计

  • 表结构要尽量遵循三大范式的原则
  • 如果查询应用多,尤其是需要进行多表查询的时候,可以进行反范式化,通过增加冗余字段增加查询效率
  • 表字段的数据类型选择合理,可以采用数值类型就不要采用字符类型;字符类型要尽可能设计的短一点,当字符串长度固定时,就采用CHAR类型,当长度不固定时,采用VARCHAR

第三步:优化逻辑查询

SQL 查询优化可以分为 ==逻辑查询优化== 和 ==物理查询优化==。

逻辑查询优化 就是改变SQL语句的内容让SQL执行效率更高,采用的方式是对SQL语句进行等价变换,对查询进行重写。

对SQL查询重写包括 子查询优化、等价谓词重写、视图重写、条件简化、连接消除和嵌套连接消除等。

第四步:优化物理查询

物理查询优化 是在确定了逻辑查询优化之后,采用物理优化技术(如索引),通过计算代价模型对各种可能的访问路径进行估算,从而找到执行方法中代价最小的作为执行计划。

第五步:使用 Redis 和 Memcached 作为缓存

除了对SQL本身进行优化以外,我们还可以将常用的数据直接放到内存中提升查询的效率

因为数据都是存放到数据库中,我们需要从数据库层中取出数据放到内存中进行业务逻辑的操作,当用户量增大的时候,如果频繁地进行数据查询,会消耗数据库的很多资源。如果我们将常用的数据直接放到内存中,就会大幅提升查询的效率。

Redis 和 Memcached 键值存储数据库都可以将数据存放到内存中。

从可靠性来说,Redis支持持久化(RDB和AOF持久化),可以让我们的数据保存在硬盘上,不过这样一来性能消耗也会比较大。而Memcached仅仅是内存存储,不支持持久化。Redis还支持数据的备份,即master-slave模式的数据备份。

从支持的数据类型来说,Redis 比 Memcached要多,Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。当我们有持久化需求或者是更高级的数据处理需求的时候,就可以使用Redis。如果是简单的 key-value存储,则可以使用Memcached。

第六步:库级优化

库级优化是在数据库的维度上进行的优化策略,如控制一个库中的数据表数量。

1、读写分离

  • 为了提升系统的性能,优化用户体验,可以采用读写分离的方式降低主数据库的负载,比如用主数据库(master)完成写操作,用从数据库(slave)完成读操作。

  • 读写分离适用于读远大于写的场景。读写分离的实现基础是主从复制,主数据库利用主从复制将自身数据的改变同步到从数据库集群中,然后主数据库负责处理写操作(当然也可以执行读操作),从数据库负责处理读操作,不能执行写操作。并可以根据压力情况,部署多个从数据库提高读操作的速度,减少主数据库的压力,提高系统总体的性能。

2、数据分片

  • 对数据库分库分表。当数据量级达到千万级以上时,有时候我们需要把一个数据库切成多份,放到不同的数据库服务器上,减少对单一数据库服务器的访问压力。如果你使用的是MySQL,就可以使用MySQL自带的分区表功能,当然你也可以考虑自己做垂直拆分(分库)、水平拆分(分表)、垂直+水平拆分(分库分表)。