【力扣数据库知识手册】数据库优化

系统的吞吐量瓶颈往往出现在数据库的访问速度上,因为数据是放在磁盘上的,读写速度无法和内存相比。

数据库结构优化

在数据库设计中,需要考虑数据冗余,查询和更新的速度、字段的数据类型是否合理等多方面的内容。

  • 将字段很多的表分解成多个表。如果有些字段的使用频率很低,可以将这些字段分离出来。
  • 增加中间表。对于经常要联合查询的表,通过建立中间表以提高查询效率,具体地,将需要通过联合查询的数据插入到中间表中,然后将原来的联合查询改为对中间表的查询。
  • 增加冗余字段。表的规范化程度越高,表和表之间的关系越多,需要连接查询的情况也就越多,性能也就越差,所以合理的加入冗余字段可以提高查询速度。

MySQL数据库CPU使用率飙升到500%的话,如何处理?

  • 先用操作系统命令top命令观察是不是mysqld占用导致的,如果不是,找出占用高的进行相关处理。
  • 如果是mysqld造成的,通过show processlist查看正在运行的线程,是不是有消耗资源的sql运行,找出其中消耗高的sql,看看执行计划是否准确,index是否缺失,或者是数据量太大造成。
  • kill掉消耗高的线程(同时观察CPU使用率是否下降),等进行相应的调整(比如说加索引、改SQL、改内存参数)之后,再重新跑这些SQL。
  • 若每个SQL消耗资源都不多,只是同一时间大量的session连进来导致CPU飙升,此时应该分析为何连接数激增。

为什么要分库分表?

  • 数据库中的数据量不一定是可控的,随着时间和业务的发展,库中的表会越来越多,表中的数据量会越来越大,相应的数据操作(增删改查)的开销也会越来越大。
  • 若不进行分布式部署,一台服务器的资源(CPU、磁盘、内存、IO)是有限的,最终数据库所能承载的数据量、数据处理能力都将遭遇瓶颈。
  • 因此,从可用性和性能两个角度出发,会对数据进行拆分处理。

如何进行分库分表?

  • 水平切分:
    • 水平分表:表结构一样,对数据进行切分,每个表的并集即全量数据;
    • 水平分库:将表水平切分至不同的数据库,水平分库伴随水平分表。
  • 垂直切分:
    • 垂直分表:将存在一张表中的字段切分到多个表,每个表结构不一样,每个表数据不一样,每个表字段的并集为原表字段;
    • 垂直分库:单个库的表分到多个库,每个库包含的表不一样,垂直分库不伴随垂直分表。
  • 混合切分:水平切分和垂直切分的组合。

分库分表存在的问题

  • 事务问题:分库分表后,就成了分布式事务。如果依赖数据库本身的分布式事务管理功能去执行事务,将付出高昂的性能代价;如果由应用程序去协助控制,形成程序逻辑上的事务,又会造成编程方面的负担。
  • 跨库跨表的JOIN问题:在执行了分库分表之后,难以避免会将原本逻辑关联性很强的数据划分到不同的表、不同的库上,这时,表的关联操作将受到限制,因为无法join不同分库的表,也无法join分表粒度不同的表。需要分多次查询才能完成。
  • 额外的数据管理负担和数据运算压力:对于数据定位和数据的增删改查,会引起额外的逻辑运算。

什么是MySQL主从复制

主从复制是指将**主数据库(Master)中的DDL和DML操作通过二进制日志传输到从数据库(Slave)**上,然后将这些日志重新执行(重做),从而使得从数据库的数据与主数据库保持一致。
作用:

  • 当主数据库出现问题时,可以切换到从数据库;
  • 可以进行数据库层面的读写分离,实现负载均衡;
  • 可以在从数据库上进行实时数据备份。

MySQL主从复制的工作原理

MySQL的主从复制是一个异步的复制过程(一般情况下感觉是实时的),数据将从一个MySQL数据库(Master)转移到另一个MySQL数据库(Slave),在两者之间实现整个主从复制的过程是由三个线程参与完成的,其中有两个线程(SQL线程和I/O线程)在Slave端,另一个线程(I/O)线程在Master端。
基本原理流程:

  • Master端:打开二进制日志(binlog)记录功能 – 记录下所有改变了数据库的语句,放进Master的binlog中;
  • Slave端:开启一个I/O线程 – 负责从Master上拉取binlog内容,放进自己的中继日志(Relay log)中;
  • Slave端:SQL执行线程 – 读取Relay log,并顺序执行该日志中的SQL事件。

MySQL读写分离的实现方案

主要基于主从复制,通过路由的方式使应用对数据库的写请求只在Master上进行,读请求在Slave端进行。
有如下四种方案:

  • 基于MySQL proxy代理
    在应用和数据库之间增加代理层,代理层接收应用对数据库的请求,根据不同请求类型转发到不同的实例,在实现读写分离的同时可以实现负载均衡。
  • 基于应用内路由
    基于应用内路由的方式即为在应用程序中实现,针对不同的请求类型去不同的实例执行SQL。具体实现可基于spring的aop:用aop来拦截spring项目的dao层方法,根据方法名称就可以判断要执行的类型,进而动态切换主从数据源。
  • 基于MySQL-Connector-Java的JDBC驱动方式
    Java程序通过在连接MySQL的JDBC中配置主库与从库等地址,JDBC会自动将读请求发送给从库,将写请求发送给主库,此外,MySQL的JDBC驱动还能实现多个从库的负载均衡。
  • 基于sharding-jdbc的方式
    sharding-spere是强大的读写分离、分表分库中间件,sharding-jdbc是sharding-sphere的核心模块

你可能感兴趣的:(数据库八股,数据库)