背景
在中小型项目的开发中,一般还是使用单一的数据库。在数据库的数据量不多的时候,sql语句想怎么写就怎么写,不要太任性。数据量一多,查询慢,连接超时,连接数不够等等各种问题涌现出来。怎么办呢?优化吧!今天就来说说关于数据库应该怎么优化的思路。
一、单个数据库的优化方案(不分库分表)
1、软优化
- 数据库参数的调整,例如连接数(默认100,最大16384)、内存量;
- 慢Sql的检索,分析执行计划,进行SQL和程序的优化;
- 优化数据库的索引结构;
- 优化数据库的表结构(该冗余的还是要冗余);
- 引入NoSql和程序结构调整(读写分离)。
参考链接:
sql优化的15个小技巧expplain使用MySQL 上亿大表如何优化?
2、硬优化
提升系统硬件(更快的IO、更多的内存):带宽、CPU、硬盘等等。
单个数据库的优化,也是有优化空间的,优化到一定程度,还是存在一些问题。更或者在设计之初,就预料到单个数据库不能满足我们的业务需求,那就分库吧,读写库分离,分库分表。
二、Mysql主从库分离(读写库)
主从库,一个主库主要负责写操作,一个或多个从库主要负责读操作。
相关资料参考:
三、分库分表
在设计分库分表之前,一定要问一下自己,为什么要分库分表?分表是为了解决单表海量数据的查询性能问题。分库是为了解决单台数据库的并发访问压力问题。
1、分库分表的概念
分库,就是将一个数据库分成多个数据库,部署到不同机器上。分表,就是一个数据库表分成多个表。分库分表方案,一种是垂直拆分,一种是水平拆分。
2、垂直拆分、水平拆分概念
垂直拆分:就是把一个有很多字段的表拆分成多个表,或分到多个库上。每个库表的结构都不一样,每个库表都包含部分字段。
水平拆分:同一个表的数据拆到不同的库不同的表中。拆分后的每个表结构保持一致。可以根据时间、地区、业务键维度、hashcode等进行拆分,最后通过路由访问到具体的数据。
3、垂直、水平拆分细化
3.1、垂直分表“⼤表拆⼩表”,基于列字段进⾏。将一张宽表(字段很多的表),按照字段的访问频次进行拆分,或者按照表单结构进行拆分。★ 业务场景表字段太多,每个字段访问频率不⼀样,浪费了IO资源,需要进⾏优化。
☝ 拆分原则
- 根据业务维度进行拆分,如订单表可以拆分为订单基本信息、订单地址、订单商品等表;
- 根据数据冷热程度拆分,20%的热点字段拆到一个表,80%的冷字段拆到另外一个表。
▶ 举个例子
有一个订单表,字段有:订单号、订单状态、订单总价、订单优惠金额、订单实际支付金额、订单地址、订单内容、订单备注、订单发票状态等等字段。
按照垂直分表,可以分为订单表1和订单表2。
订单表1中的字段有:订单号、订单状态、订单总价、订单优惠金额、订单实际支付金额等。
订单表2中有订单号、订单地址、订单内容、订单备注、订单发票状态字段等。
2、垂直分库
根据不同的业务,将表进行分类,拆分到不同的数据库。这些库可以部署在不同的服务器,分摊访问压力。
★ 业务场景项目里面单个数据库的CPU、内存⻓期处于90%+的利⽤率,数据库连接经常不够,需要进⾏优化。
☝ 拆分原则对一个系统中的不同业务进行拆分, 数据库的连接资源比较宝贵且单机处理能力也有限。
▶ 举个例子现有数据库1、数据库2,并且有订单表和商品评论表。根据业务场景的不同,将订单表存储在数据库1中,而商品评论表存储在数据库2中。
3、水平分表
水平分表:将一张表的数据(按照数据行) ,分配到同一个数据库的多张表中,每个表都只有一部分数据,表结构一样数据不⼀样。
★ 业务场景当⼀张表的数据达到⼏千万时,查询⼀次所花的时间长速度慢,需要进⾏优化,缩短查询时间。
☝ 拆分原则大表拆小表(垂直分表:表结构拆分;⽔平分表:数据拆分),把⼀个表的数据分到⼀个数据库的多张表中,每个表只有这个表的部分数据。
▶ 举个例子现有数据库1,在数据库1中有多个订单表order1、order2,分表规则通过id对2取余,订单id没有余数的订单数据存order1表中,订单号有余数的订单数据存储在order2表中,订单表1中的数据 + 订单表2中的数据才是全部的订单数据。
4、水平分库
将一张表的数据(按照数据行) 分到多个不同的数据库。每个库的表结构相同,数据不相同没有交集。水平分库比水平分表的粒度更大。
★ 业务场景:高并发的项目中,水平分表后访问压力依旧在单个库上,1个数据库资源瓶颈 CPU/内存/带宽等限制导致响应慢,需要进行优化。
☝ 拆分原则把同个表的数据按照⼀定规则分到不同的数据库中。
▶ 举个例子:现有数据库1、数据库2,并且两个数据库中都有order订单表。根据分表规则通过id对2取余,订单id没有余数的订单数据存在数据库1的order表中,订单号有余数的订单数据存储在数据库2的order表中。
5、分表分库所带来的问题
- 跨节点数据库Join关联查询和多维度查询;
- 分库操作带来的分布式事务问题;
- 执行SQL排序、分页、函数计算等问题;
- 数据库全局主键重复问题;
- 分库分表后⼆次扩容问题;
- 分库分表技术选型问题。
解决旧问题,又来新问题。问题5需要怎么解决呢,这就用到了分库分表中间件,今天就找到了一个,有机会要用起来。
SpringBoot + Sharding JDBC 分库分表
最 后 总 结
数据库的优化,一般是遇到什么问题就解决什么问题。平时编码的时候,需要注意sql优化和程序优化。单个数据库的优化达到瓶颈,就需要考虑主从库读写分离,甚至分库分表。分库分表需要找一个可靠的中间件来帮忙。如果是从0开始的项目,最好在设计数据库之初就根据业务场景来考虑这些问题。
以上便是我的调查,希望对你有帮助。