【数据库】性能优化问题——分库分表

数据库性能问题

原因

  • 大量请求阻塞

    在高并发场景下,大量请求都需要操作数据库,导致连接数不够了,请求处于阻塞状态。

  • SQL操作变慢

    如果数据库中存在一张上亿数据量的表,一条 SQL 没有命中索引会全表扫描,这个查询耗时会非常久。

  • 存储出现问题

    业务量剧增,单库数据量越来越大,给存储造成巨大压力。

优化方案

  • 硬件

    • 增加机器性能
  • 软件

    • SQL调优

      • SQL调优的目的:让慢SQL变快,让SQL执行尽量命中索引,不命中索引会全表查询,则性能变慢

      • 开启慢 SQL 记录

        如果你使用的是 Mysql,需要在 Mysql 配置文件中配置几个参数即可。
        slow_query_log=on
        long_query_time=1
        slow_query_log_file=/path/to/log

      • 调优的工具

        常常会用到 explain 这个命令来查看 SQL 语句的执行计划,通过观察执行结果很容易就知道该 SQL 语句是不是全表扫描、有没有命中索引。

        • 有一列叫“type”,常见取值有:
          ALL、index、range、 ref、eq_ref、const、system、NULL(从左到右,性能从差到好)
    • 表结构优化

      • 数据库表冗余字段

        “user”表中有 user_id、nickname 等字段,“order”表中有order_id、user_id等字段,如果想拿到用户昵称怎么办?一般情况是通过 join 关联表操作,在查询订单表时关联查询用户表,从而获取导用户昵称。

        • 弊端,如果这个字段更新会同时涉及到多个表的更新,因此在选择冗余字段时要尽量选择不经常更新的字段。
    • 读写分离

    • 数据库集群

      • 当发现读请求明显多于写请求时,我们可以让主实例负责写,从实例对外提供读的能力;
        如果读实例压力依然很大,可以在数据库前面加入缓存如 redis,让请求优先从缓存取数据减少数据库访问。
    • 分库分表

      • 分库

        • 从一个大的数据中分出多个小的数据库,每个服务都对应一个数据库,这就是系统发展到一定阶段必要要做的“分库”操作。
      • 分表

        • 水平拆分和垂直拆分

          • 垂直拆分

            • 垂直切分:基于表或字段划分,表结构不同。
            • 一张用户表拆分为了用户基本信息表+用户详细信息表,两张表结构不一样相互独立
          • 水平拆分

            • 水平切分:基于数据划分,表结构相同,数据不同。
            • 每日表:只存储当天的数据。
              每月表:可以起一个定时任务将前一天的数据全部迁移到当月表。
              历史表:同样可以用定时任务把时间超过 30 天的数据迁移到 history表。
        • 单库内分表和多库内分表

          • 多库拆分

            • 遇到问题:单数据库瓶颈
            • 将子表拆分成多个数据库,拆分成的两个子表分别存在不同的数据库中
      • 缺点

        • 跨数据库关联查询的缺点,不能使用join操作关联多张表查询数据

          • 字段冗余:把需要关联的字段放入主表中,避免 join 操作;
          • 数据抽象:通过ETL等将数据汇合聚集,生成新的表;
          • 全局表:比如一些基础表可以在每个数据库中都放一份;
          • 应用层组装:将基础数据查出来,通过应用程序计算组装;
        • 分布式事务

          • 基于可靠消息(MQ)的解决方案
          • 两阶段事务提交、柔性事务
        • 排序、分页、函数计算问题

          • 先在每个分片上执行相应的函数,然后将各个分片的结果集进行汇总和再次计算,最终得到结果。
        • 分布式 ID

          • 使用 Mysql 数据库在单库单表可以使用 id 自增作为主键,分库分表了之后就不行了,会出现id 重复。

          • 分布式 ID 解决方案

            • UUID
            • 基于数据库自增单独维护一张 ID表
            • 号段模式
            • Redis 缓存
            • 雪花算法(Snowflake)
            • 百度uid-generator
            • 美团Leaf
            • 滴滴Tinyid
        • 多数据源

          • 客户端适配和代理层适配。
posted @ 2021-04-14 10:07  your_棒棒糖  阅读(55)  评论(0编辑  收藏  举报