Mysql大表优化

433 阅读4分钟
大表如何优化?
  • 限定数据的范围:避免不带任何限制数据范围条件的查询语句。
  • 读写分离:主库负责写,从库负责读。
  • 垂直分表:将一个表按照字段分成多个表,每个表存储其中一部分字段。
  • 水平分表:在同一个数据库内,把一个表的数据按照一定规则拆分到多个表中。
  • 对单表进行优化:对表中的字段、索引、查询SQL进行优化。
  • 添加缓存
什么是垂直分表、垂直分库、水平分表、水平分库?

垂直分表:将一个表按照字段分成多个表,每个表存储其中一部分字段。一般会将常用的字段放到一个表中,将不常用的字段放到另一个表中。

垂直分表的优势:

  • 避免IO竞争减少锁表的概率。因为大的字段效率更低,第一数据量大,需要的读取时间长。第二,大字段占用的空间更大,单页内存储的行数变少,会使得IO操作增多。
  • 可以更好地提升热门数据的查询效率。

垂直分库:按照业务对表进行分类,部署到不同的数据库上面,不同的数据库可以放到不同的服务器上面。

垂直分库的优势:

  • 降低业务中的耦合,方便对不同的业务进行分级管理。
  • 可以提升IO、数据库连接数、解决单机硬件资源的瓶颈问题。

垂直拆分(分库、分表)的缺点:

  • 主键出现冗余,需要管理冗余列
  • 事务的处理变得复杂
  • 仍然存在单表数据量过大的问题

水平分表:在同一个数据库内,把同一个表的数据按照一定规则拆分到多个表中。

水平分表的优势:

  • 解决了单表数据量过大的问题
  • 避免IO竞争并减少锁表的概率

水平分库:把同一个表的数据按照一定规则拆分到不同的数据库中,不同的数据库可以放到不同的服务器上。

水平分库的优势:

  • 解决了单库大数据量的瓶颈问题
  • IO冲突减少,锁的竞争减少,某个数据库出现问题不影响其他数据库(可用性),提高了系统的稳定性和可用性

水平拆分(分表、分库)的缺点:

  • 分片事务一致性难以解决
  • 跨节点JOIN性能差,逻辑会变得复杂
  • 数据扩展难度大,不易维护

在系统设计时应根据业务耦合来确定垂直分库和垂直分表的方案,在数据访问压力不是特别大时应考虑缓存、读写分离等方法,若数据量很大,或持续增长可考虑水平分库分表,水平拆分所涉及的逻辑比较复杂,常见的方案有客户端架构和恶代理架构。

分库分表后,ID键如何处理?

分库分表后不能每个表的ID都是从1开始,所以需要一个全局ID,设置全局ID主要有以下几种方法:

  • UUID:优点:本地生成ID,不需要远程调用;全局唯一不重复。缺点:占用空间大,不适合作为索引。
  • 数据库自增ID:在分库分表表后使用数据库自增ID,需要一个专门用于生成主键的库,每次服务接收到请求,先向这个库中插入一条没有意义的数据,获取一个数据库自增的ID,利用这个ID去分库分表中写数据。优点:简单易实现。缺点:在高并发下存在瓶颈。系统结构如下图(图片来源于网络)
  • Redis生成ID:优点:不依赖数据库,性能比较好。缺点:引入新的组件会使得系统复杂度增加
  • Twitter的snowflake算法:是一个64位的long型的ID,其中有1bit是不用的,41bit作为毫秒数,10bit作为工作机器ID,12bit作为序列号。

1bit:第一个bit默认为0,因为二进制中第一个bit为1的话为负数,但是ID不能为负数.

41bit:表示的是时间戳,单位是毫秒。

10bit:记录工作机器ID,其中5个bit表示机房ID,5个bit表示机器ID。

12bit:用来记录同一毫秒内产生的不同ID。

  • 美团的Leaf分布式ID生成系统