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

server/2024/10/25 8:08:00/

当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.ppmy.cn/server/134652.html

相关文章

华为ICT题库-大数据部分

1475、以下哪项组件不属于大数据平台中的组件&#xff1f;&#xff08;云服务考点&#xff09; (A)MapReduce (B)Yarn (C) openStack (D)HDFS 答案&#xff1a;C 解析&#xff1a;组件OpenStack不属于大数据平台中的组件。OpenStack是一个开源的云计算平台&#xff0c;它提供…

sql获取时间差

MySQL SELECT TIMESTAMPDIFF(HOUR, 2023-10-01 12:00:00, 2023-10-02 15:30:00) AS hours_difference; PostgreSQL //EXTRACT(EPOCH FROM (2023-10-02 15:30:00::timestamp - 2023-10-01 12:00:00::timestamp)) // 获取的是两个时间相差的秒数&#xff0c;在此基础上除3600获…

windows环境下vscode编写c语言连接mysql

创建一个文件夹test02 在文件夹中创建test.c文件 用vscode打开test02文件夹 自动生成tasks.json和launch.json文件&#xff0c;需要安装这里通C/C Runner插件来自动生成json文件和一些文件夹。 接下来配置mysql 本地已经安装了mysql数据库&#xff0c;此安装过程省略。 有…

logdata-anomaly-miner:一款安全日志解析与异常检测工具

关于logdata-anomaly-miner logdata-anomaly-miner是一款安全日志解析与异常检测工具&#xff0c;该工具旨在以有限的资源和尽可能低的权限运行分析&#xff0c;以使其适合生产服务器使用。 为了确保 logdata-anomaly-miner的正常运行&#xff0c;推荐安装了python > 3.6的…

如何构建一个支持GPU的Llamafile容器

用CPU玩那些大型的语言模型确实挺有意思的&#xff0c;但看着电脑一个字一个字地慢慢显示结果&#xff0c;那股兴奋劲儿很快就过去了。让这些语言模型软件在GPU上跑起来可能会有点麻烦&#xff0c;因为这得看你的系统和硬件支不支持。我这篇文章就是想告诉你&#xff0c;怎么在…

【Linux】Linux进程间通信

1.进程间通信 进程之间具有独立性&#xff0c;进程间如果要发生通信&#xff0c;就需要打破这种独立性。进程间通信必定需要一块公共的区域来作为信息的存放点&#xff0c;操作系统需要直接或间接给通信进程双方提供内存空间&#xff0c;例如这块内存空间就是文件系统提供的&a…

【 xiangshan分支预测单元结构及时序介绍】

xiangshan分支预测单元结构及时序介绍 1.1 子预测器接口信号1 in2 out3 流水线控制信号4 update更新请求5 redirect重定向请求 1.2 预测器接口连接1.3 分支预测单元时序介绍1.3.1 一周期无空泡预测 1.3.2 预测结果重定向1.4 相关使能信号 本节主要介绍xiangshan BPU内部是如何整…

Django+Vue全栈开发项目入门(一)

Vue项目搭建过程 1、使用脚手架工具搭建项目 2、准备静态资源 3、调整生成项目结构 使用脚手架工具搭建项目 网络请求库axios Axios是一个基于Promise的HTTP库&#xff0c;适用于浏览器和node.js环境&#xff0c;用于发送网络请求。 特点 跨平台性&#xff1a;Axios既可…