问: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.mzph.cn/web/56544.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

优先算法——移动零(双指针)

目录 1. 题目解析 2. 算法原理 3.代码实现 题目: 力扣题目链接&#xff1a;移动零 1. 题目解析 题目截图如下&#xff1a; 不过要注意&#xff0c;这个移动题目要求是在原数组中原地操作&#xff0c;不能新额外开辟一个数组来修改。 2. 算法原理 这个原理可以称之为数…

node和npm

背景&#xff08;js&#xff09; 1、为什么js能操作DOM和BOM? 原因&#xff1a;每个浏览器都内置了DOM、BOM这样的API函数 2、浏览器中的js运行环境&#xff1f; v8引擎&#xff1a;负责解析和执行js代码 内置API&#xff1a;由运行环境提供的特殊接口&#xff0c;只能在所…

Python | Leetcode Python题解之第507题完美数

题目&#xff1a; 题解&#xff1a; class Solution:def checkPerfectNumber(self, num: int) -> bool:if num 1:return Falsesum 1d 2while d * d < num:if num % d 0:sum dif d * d < num:sum num / dd 1return sum num

使用预训练的BERT进行金融领域问答

获取更多完整项目代码数据集&#xff0c;点此加入免费社区群 &#xff1a; 首页-置顶必看 1. 项目简介 本项目旨在开发并优化一个基于预训练BERT模型的问答系统&#xff0c;专注于金融领域的应用。随着金融市场信息复杂性和规模的增加&#xff0c;传统的信息检索方法难以高效…

Python 爬虫项目实战:爬取某云热歌榜歌曲

一、网络爬虫的定义 网络爬虫&#xff08;Web Crawler&#xff09;&#xff0c;也成为网页蜘蛛或者网页机器人&#xff0c;是一种按照既定规则自动浏览网络并提取信息的程序。爬虫的主要用途包括数据采集、网络索以及内容抓取等。 二、爬虫基本原理 1、种子URL&#xff1a;爬…

01 springboot-整合日志(logback-config.xml)

logback-config.xml 是一个用于配置 Logback 日志框架的 XML 文件&#xff0c;通常位于项目的 classpath 下的根目录或者 src/main/resources 目录下。 Logback 提供了丰富的配置选项&#xff0c;可以满足各种不同的日志需求。需要根据具体情况进行配置。 项目创建&#xff0…

CCF-BDCI大数据与计算智能大赛TOP4-京东生鲜

2023 CCF 大数据与计算智能大赛《线上线下全场景生鲜超市库存履约一体化决策》top4南山论剑 摘要1 数据预处理1.1 数据整合1.2 数据划分 2 特征工程2.1 静态特征2.2 动态特征 3 方案设计3.1 数据构造3.2 模型训练3.3 模型融合3.4库存分配3.5 方案对比 链接: CCFBDCI-线上线下全…

解决:如何在opencv中得到与matlab立体标定一样的矫正图?(python版opencv)

目的&#xff1a;采用一样的标定参数&#xff0c;matlab中和opencv中的立体矫正图像是一样的吗&#xff1f;不一样的话怎么让它们一样&#xff1f; 结论&#xff1a;不一样。后文为解决方案。 原因&#xff1a;注意matlab的标定结果在matlab中的用法和在opencv中的用法不一样&a…

STM32 从0开始系统学习2

目录 C语言基础 位操作 extern 修饰符 typedef 封装复杂的类型 寄存器基础知识 STM32F103架构简单描述&#xff08;建议先不看&#xff09; 存储器映射 寄存器映射 寄存器地址计算 下面简单的聊一聊一些需要的前置知识基础。 C语言基础 位操作 这个在单片机里算基操…

Windows通过netsh控制安全中心防火墙和网络保护策略

Windows通过netsh控制安全中心防火墙和网络保护策略 1. 工具简介 【1】. Windows安全中心 【2】. netsh工具 netsh(Network Shell) 是一个Windows系统本身提供的功能强大的网络配置命令行工具。 2. 开启/关闭防火墙策略 在设置端口&#xff08;禁用/启用&#xff09;前&am…

中国人寿财险青岛市分公司普惠金融助力民生保障

普惠金融是金融业的重要组成部分&#xff0c;也是服务实体经济、保障民生的重要途径。国寿财险青岛市分公司始终坚持以人民为中心的发展思想&#xff0c;大力发展普惠金融业务&#xff0c;不断提升金融服务的覆盖面和便捷性。 在服务“三农”方面&#xff0c;国寿财险青岛市分…

【宝塔面板】宝塔面板使用docker部署chatGPT-Next-web

1111111 chatGPT-Next-web大家并不陌生&#xff0c;就是下面的这个界面&#xff0c;下面请大家跟随小编部署下这个web 我们先感谢下源码的博主&#xff1a; https://github.com/Dooy/chatgpt-web-midjourney-proxy 本教程部署也很简单&#xff0c;就2步 1、创建容器编排模版 …

云原生后端概述

目录 云原生后端概述 云原生后端的核心特点 云原生后端的架构组件 云原生后端的常见技术栈 云原生后端与传统后端架构的对比 结论 云原生后端概述 随着企业对数字化转型需求的不断增加&#xff0c;云原生后端逐渐成为构建现代应用程序的核心方法。云原生&#xff08;Clo…

股票基金大通证券申购大宗交易代理-VUE源码开源版

前后端vue开源 服务端java开源 这套是开源的 1.环境 环境 php7.4 sql 5.7 Nginx1.2 tomcat-8 redis 放行1-65535 2.创建5个网站。xxx.com替换你的域名 ftp.xxx.com api.xxx.com agent.xxx.com admin.xxx.com wap.xxx.com api设置反向代理 代理名称 api 目标URL http://127.…

Spring boot快速集成开发

目录 1. 创建 Spring Boot 项目 2. 项目结构 3. 编写代码 3.1 创建实体类 3.2 创建数据访问层 3.3 创建服务层 3.4 创建控制器 4. 配置数据库 5. 启动应用 6. 运行项目 7. 测试 API 8. H2 控制台 在 Spring Boot 中快速集成开发的步骤通常包括创建项目、添加依赖、编写…

Qt 学习第 天:线程与多线程

1024程序员快乐&#xff0c;如果这博客让你学习到了知识&#xff0c;请给我一个免费的赞❤️ 一、创建界面文件 LCDnumber 二、创建mythread类&#xff0c;继承QObject 三、在MyThread.h文件做修改&#xff0c;并且加上函数声明 引入头文件&#xff0c;改变继承 #ifndef MY…

迁移学习|ResNet18

一、导入库 二、设置随机种子 三、数据增强和数据加载 四、加载预训练模型 五、定义损失函数和优化器 六、学习率调度器 七、训练模型 八、可视化训练过程 九、总结 1. 常见优化器概述 1.1 随机梯度下降&#xff08;SGD: Stochastic Gradient Descent&#xff09; 简介&…

C++图形库

建议大家多逛逛GitHub&#xff0c;特别是DevWeekly&#xff0c;它每周都会筛选一些优秀的开源项目、开源工具、技术文章等&#xff0c;可以多去看看。接下来不废话了&#xff0c;列举一些我认为较好的C图形库&#xff0c;希望对大家学习有帮助。 NanoVG NanoVG是一个2D图形库…

使用yield压平嵌套字典有多简单?

我们经常遇到各种字典套字典的数据&#xff0c;例如&#xff1a; nest_dict {a: 1,b: {c: 2,d: 3,e: {f: 4}},g: {h: 5},i: 6,j: {k: {l: {m: 8}}} } 有没有什么简单的办法&#xff0c;把它压扁&#xff0c;变成&#xff1a; {a: 1,b_c: 2,b_d: 3,b_e_f: 4,g_h: 5,i: 6,j_k_l_…

【Linux系统内核探索】进程调度

文章目录 进程调度什么是进程调度&#xff1f;进程调度算法task_struct的链式结构 总结 进程调度 什么是进程调度&#xff1f; 进程调度是操作系统内核的核心功能之一&#xff0c;负责在多个进程之间分配CPU时间&#xff0c;使得系统能够同时运行多个进程。因为计算机的CPU资…