当前位置: 首页 > article >正文

问:MySQL表过大,你有哪些优化实践?

当MySQL单表记录数过大时,数据库的CRUD(创建、读取、更新、删除)性能会明显下降。为了提升性能,我们需要采取一些优化措施。本文将详细介绍几种常见的优化方案。

1. 限定数据的范围

描述

务必禁止不带任何限制数据范围条件的查询语句。例如,在查询订单历史时,可以控制在一个月的范围内。

示例

-- 不推荐的查询
SELECT * FROM orders;

-- 推荐的查询
SELECT * FROM orders WHERE order_date >= '2023-09-01' AND order_date < '2023-10-01';

优点

  • 提高查询性能,避免全表扫描。

缺点

  • 需要在业务代码中添加范围限制逻辑。

2. 读/写分离

描述

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

架构图

读写分离示意

主库(写) -> 从库(读)

示例

通过配置数据库连接池实现读写分离,例如使用MyCat等中间件。

优点

  • 减轻主库压力,提高读写性能。

缺点

  • 数据同步延迟问题。
  • 架构复杂度增加。

3. 垂直分区

描述

根据数据库里面数据表的相关性进行拆分。例如,将用户表拆分成用户登录表和用户信息表。

示例

-- 用户登录表
CREATE TABLE user_login (
    user_id INT PRIMARY KEY,
    username VARCHAR(50),
    password VARCHAR(50)
);

-- 用户信息表
CREATE TABLE user_info (
    user_id INT PRIMARY KEY,
    email VARCHAR(100),
    phone VARCHAR(20)
);

优点

  • 列数据变小,减少I/O次数。
  • 简化表结构,易于维护。

缺点

  • 主键冗余。
  • 需要管理冗余列,引起Join操作。
  • 事务变得更加复杂。

4. 水平分区

描述

保持数据表结构不变,通过某种策略存储数据分片。每一片数据分散到不同的表或库中。

示例

将用户表按用户ID进行水平拆分。

-- 用户表1
CREATE TABLE user_1 (
    user_id INT PRIMARY KEY,
    username VARCHAR(50),
    email VARCHAR(100)
);

-- 用户表2
CREATE TABLE user_2 (
    user_id INT PRIMARY KEY,
    username VARCHAR(50),
    email VARCHAR(100)
);

策略

  • Range Partitioning(范围分区)
  • List Partitioning(列表分区)
  • Hash Partitioning(哈希分区)

优点

  • 支持非常大的数据量。
  • 提高查询性能。

缺点

  • 分片事务难以解决。
  • 跨节点Join性能较差。
  • 逻辑复杂。

5. 数据库分片

客户端代理

描述

分片逻辑在应用端,封装在jar包中,通过修改或封装JDBC层来实现。例如当当网的Sharding-JDBC、阿里的TDDL。

示例

使用Sharding-JDBC进行分片。

// 配置数据源和分片规则
Map<String, DataSource> dataSourceMap = new HashMap<>();
dataSourceMap.put("ds0", createDataSource("jdbc:mysql://localhost:3306/db0"));
dataSourceMap.put("ds1", createDataSource("jdbc:mysql://localhost:3306/db1"));

ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
shardingRuleConfig.getBindingTableGroups().add("t_order");

TableRuleConfiguration orderTableRuleConfig = new TableRuleConfiguration("t_order", "ds${0..1}");
orderTableRuleConfig.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("order_id", "t_order_${order_id % 2}"));
shardingRuleConfig.getTableRuleConfigs().add(orderTableRuleConfig);

ShardingDataSource shardingDataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, new Properties());

// 使用分片数据源
try (Connection conn = shardingDataSource.getConnection()) {
    Statement stmt = conn.createStatement();
    stmt.executeQuery("SELECT * FROM t_order");
}

中间件代理

描述

在应用和数据中间加了一个代理层,分片逻辑统一维护在中间件服务中。例如Mycat、360的Atlas、网易的DDB。

示例

配置Mycat进行分片。

<!-- mycat 配置文件 -->
<schema>
    <table name="t_order" primaryKey="order_id" dataNode="dn1,dn2" rule="sharding-by-order-id">
    </table>
</schema>

<dataNode>
    <name>dn1</name>
    <dataHost>localhost1</dataHost>
    <database>db1</database>
</dataNode>

<dataNode>
    <name>dn2</name>
    <dataHost>localhost2</dataHost>
    <database>db2</database>
</dataNode>

<rule>
    <columns>order_id</columns>
    <algorithm>sharding-by-order-id</algorithm>
</rule>

方案比较

方案描述优点缺点适用场景
限定数据范围控制查询范围,避免全表扫描提高查询性能业务代码中需添加范围限制逻辑所有查询操作
读写分离主库负责写,从库负责读减轻主库压力,提高读写性能数据同步延迟,架构复杂度增加读写操作频繁的系统
垂直分区数据表按列拆分列数据变小,减少I/O次数,简化表结构,易于维护主键冗余,需管理冗余列,引起Join操作,事务复杂表列多,部分列访问频繁
水平分区数据表按行拆分支持大数据量,提高查询性能分片事务难解决,跨节点Join性能差,逻辑复杂单表数据量巨大
客户端代理分片分片逻辑在应用端,封装在JDBC层应用端改造少,支持大数据量存储分片事务难解决,跨节点Join性能差,逻辑复杂,需额外维护分片逻辑中小型系统,客户端改造方便
中间件代理分片分片逻辑在中间件,应用与数据库之间加代理层应用端无需改造,支持大数据量存储,分片逻辑集中管理中间件性能瓶颈,架构复杂度增加,需额外维护中间件大型系统,需统一管理分片逻辑

结语

优化大表的方法多种多样,选择哪种方案取决于具体的业务需求和系统架构。在优化过程中,需要权衡各种因素,如性能、复杂度、维护成本等。希望本文的内容能帮助大家更好地理解和应用大表优化方案,提升数据库性能。


http://www.kler.cn/news/365973.html

相关文章:

  • 理解深度学习模型——高级音频特征表示的分层理解
  • 【Qt聊天室客户端】聊天界面功能
  • TDengine 签约新奥新智:写入速度提升10倍,成本降低90%
  • 手动改造UPX壳,增加IAT保护
  • mac电脑设置chrome浏览器语言切换为日语英语等不生效问题
  • 东方博宜1180 - 数字出现次数
  • 【SSM详细教程】-12-一篇文章了解SpringMVC
  • 新手做私域学会这三步,一周时间营收翻倍
  • React五官方文档总结二状态管理
  • Java 集合框架:List、Set、Map 特性、创建方式与遍历方式总结
  • flask服务通过gunicorn启动
  • 深度学习模型入门教程:从基础到应用
  • Debian及其衍生系统安装Python
  • 「AIGC」n8n AI Agent开源的工作流自动化工具
  • C++学习,标准库 <climits>
  • LLM | 论文精读 | 基于大型语言模型的自主代理综述
  • 整合全文检索引擎 Lucene 添加站内搜索子模块
  • pytorh学习笔记——cifar10(四)用VGG训练
  • 【TabBar嵌套Navigation案例-常见问题按钮-获取数据 Objective-C语言】
  • Mysql主主互备配置
  • 全球著名哲学家思想家起名大师颜廷利:爱屋及乌背后的教育意义
  • 等保测评的主要内容
  • React 前端框架概述
  • 如何预防数据打架?数据仓库如何保持指标数据一致性开发指南(持续更新)
  • 短视频矩阵系统源码开发优势,短视频矩阵系统oem部署
  • 使用铭文思路对智能合约改进