大表优化

zszdevelop数据库大约 3 分钟

大表优化

当MySQL单表记录数据过大,数据库的CRUD性能会明显下降,一些常见的优化措施

1. 限制数据的范围

务必禁止不带任何限制数据范围的查询语句

例如:我们当用户在查询订单历史的时候,可以控制在一个范围内;

2. 读/写分离

经典的数据库拆分方案,主库负责写,从库负责读

3. 垂直分区

根据数据库里面的数据表的相关性进行拆分

例如:用户表中既有用户登录信息又有用户基本信息,可以将用户表拆分成两个单独的表,甚至放到单独的库做分库

简单来说垂直拆分是指数据表列的拆分,把一张列比较多的表拆分为多张表

如下图

image-20190913195804469
image-20190913195804469

3.1 垂直拆分的优缺点

  • 优点

    • 可以使得列数据变小,在查询时减少读取的block数,减少I/O次数
    • 简化表结构,易于维护
  • 缺点

    • 主键会出现冗余,需要管理冗余列
    • 并会引起join操作,可以通过在应用层进行Join来解决
    • 会让事务变得更加复杂

4. 水平分区

保持数据表结构不变,通过某种策略存储数据分片,这样每一片数据分散到不同的表或者库中,达到了分布式的目的。水平拆分可以支持非常大的数据量

水平拆分是指数据表行的拆分,表的行数超过200万行时,就会变慢,这时可以把一张的表的数据拆成多张表来存放。

举个例子,我们可以将用户信息表拆分成多个用户信息表,这样可以避免单一表数据量过大对性能造成的影响

image-20190913202054918
image-20190913202054918

水平拆分可以支持非常大的数据量

需要注意的一点是:分表仅仅是解决了单一表数据过大的问题,但由于表的数据还是在同一台机器上,其实对于提升Mysql并发能力没有意义。所以水平拆分最好分库

4.1 水平拆分总结

水平拆分能够支持非常大的数据量存储,应用端改造也少,但分片事务难以解决,跨节点join性能较差,逻辑复杂。

尽量不要对数据进行分片,因为拆分会带来逻辑、部署、运维等各种复杂度,一般的数据表在优化得当的情况下支撑千万以下的数据量是没有太大问题的。如果实在要分片,尽量选择客户端分片架构,这样可以减少一次和中间件的网络I/O

4.2 数据库分片两种方案

  • 客户端代理

    分片逻辑在应用端,封装在jar包中,通过修改或者封装JDBC层来实现

    • 当当网的Sharding-JDBC
    • 阿里的TDDL是两种比较常用的实现
  • 中间件代理

    在应用和数据中间加了一层代理层,分片逻辑统一维护在中间件服务中

    • Mycat
    • 360的Atlas
    • 网易的DDB
Loading...