对于MySQL的性能优化,可能会想到索引优化。但是如果在数据量很大的情况(100w以上),而且写操作比较多的情况下,优化索引性能提升不明显。传统的分库分表是通过应用层逻辑实现的
分库分表
把单一的数据库拆分成若干的数据库,将原来数据大表分成若干数据表,使得单一数据库、单一数据表的数量变小(数据量也随着拆分而变少),从而解决数据库由于数据量过大而导致性能降低的问题。
分库分表的方式
1) 垂直分表
(按照数据表结构划分)
为了解决单一表
数据量过大的问题,把一张宽表按照字段使用频率的高低、是否大字段的原则分为2张或多张表,即常用的(放在前端用于浏览的数据)放一张表,不常用的(详情的数据)放另一张表。
性能提升:
- 避免IO争夺并减少锁表的几率(浏览信息和查看详情互不干扰)
- 充分发挥热门数据的操作效率,操作效率高的数据不会被低效率的数据拖累
存在缺点:
- 大字段的IO查找效率低
1.由于本身数据量大,需要更长时间读取;
2.跨页问题。页是数据库的存储单位,很多的查找是以页为单位,单页内数据行越多数据库整体性能更好;而大字段占用空间大,单页内存储的行数少,因此IO效率低;
3.字段长度短的数据性能会高写。数据库以行为单位把数据加载到内存中,数据表中字段长度较短,且访问频率高的数据,内存能加载更多数据,因此命中率更高,而且减少了磁盘IO,从而提升了数据库性能。
垂直分表规则
- 把不常用的列放在一张表中
- 把大的字段(text,blob)拆分出来放在附表
- 把经常用于组合查询的字段放在一个表
2) 垂直分库(常用于分布式系统开发)
(按照数据表结构划分)
虽然垂直分表能有一定的性能提升,但还是处于同一个数据库中,就是说还是在同一个服务器中,每个表会竞争同一个物理机的CPU、磁盘、内存、网络IO等资源。
因此,垂直分库根据业务的耦合松紧,将表进行分类,并把表放在不同数据库,并且把数据库部署在不同的服务器上(专库专用),从而让多个服务器共同分摊压力。
性能提升:
- 解决业务上的耦合,业务清晰。(店铺数据库,商品数据库)
- 能对不同业务进行分级管理、维护、监控、扩展等
- 在高并发场景下,能在一定程度上提升IO、数据库连接数、降低单机硬件资源的瓶颈
存在缺点:
- 还是没有解决单表数据量过大的问题
- 要解决跨库带来的复杂问题
3) 水平分库
(按照数据行划分)
经过垂直分库后,数据库性能确实有提升。但是随着业务的增长,难以再细粒度地进行垂直划分,单个数据库存储的数量也超出了预估。
可尝试采用水平分库,把同一个表的数据行按照一定的规则拆到不同的数据库中(user_DB1 user_DB2),数据表结构不变,然后每个数据库部署到不同服务器。
这种规则可以有很多,例如根据id的奇偶性,DB [id%2+1]
分在不同的数据库 DB1 DB2
对比:垂直分库是把不同的表拆到不同数据库,是根据不同业务对数据进行拆分
性能提升:
- 解决了单库大数据问题,以及高并发的性能瓶颈
- 提高了系统的稳定性(IO冲突少,锁减少)和可用性(某个库出现问题,不影响全部,还有部分可用)
存在缺点:
同一个表被分在不同数据库中,需要额外进行数据操作的路由工作,因此大大提升了系统的复杂度,运维成本增加
4) 水平分表
(按照数据行划分)
以上三种方法都为了减少单表的数据量,但如果单表的数据量还是很大,继续进行水平分库的话,数据库实例就会很多,因此可以把思路放在表上。
水平分表是在同一个数据库内,把同一个表的数据按照一定规则拆到多个表中(对数据行的拆分,不影响表结构)
思路和水平分库相似,只是划分对象是数据表。对每个垂直划分出来的表A(商品信息)B(店铺信息),根据每个表的id奇偶性,分在不同的表,如表A[id%2+1]
(A1表存id为偶数,A2表存id为奇数)
性能提升:
- 优化单一表数据量过大而引发的性能问题,分出来的小表只包含一部分数据,从而使得单表数据量变小,提升检索性能
- 避免争夺IO,并减少锁表几率
分库分表存在的问题
事务一致性问题: 不同服务器的数据库实例完成一个事务会出现分布式事务问题
跨界点关联查询问题: 数据不在同一个数据库,则不能通过一个sql语句进行关联查询。需要对每个数据进行查询,再拼接一起
公共表: 不同数据库可能依赖一张公共表,但没必要对这张公共表拆分。因此需要在不同数据库中分别建立对应的公共表
主键避重: 表中数据存在不同数据库中,某个分区的id无法保证全局唯一,自增长也没有用。因此应该建立全局主键
MySQL分区表
工作原理
对用户来说,分区表是独立的逻辑表,但是MySQL底层将其分成多个物理子表,每一个分区表都是独立的表文件,这些对于用户来说是透明的。
创建表时使用partition by子句定义每个分区存放的数据,执行查询时,优化器会根据分区定义过滤没有我们所需数据的分区,使得查询时只查询数据所在分区即可。
分区类型
- key 奇偶性
- 范围分区
- 哈希分区
- List分区