您的当前位置:首页>全部文章>文章详情

【MySql】mysql数据库表分区设计实现

CrazyPanda发表于:2024-07-16 10:37:09浏览:388次TAG:

原文链接https://blog.csdn.net/weixin_45377154/article/details/135285902

文章目录



前言

数据库单表数据量不断增大,设计表分区来提高数据库的查询效率。

一、什么是mysql表分区?

mysql表分区是将一个大表拆分成更小的,可管理的部分的技术,通过将数据分布在多个分区中,可以提高查询性能,简化备份和恢复操作,并允许更有效的处理大量数据。
表分区可以根据不同的条件进行分割,例如按范围、列表、哈希或者键值分区。每个分区都类似于独立的子表,具有自己的存储结构和索引,这意味着可以根据查询的条件搜索特定分区,而不必要扫描政整个表。
使用表分区的好处:
1、查询性能提升:分区可以使得查询只针对特定的分区进行,从而减少了需要扫描的数据量,提高了查询效率。
2、管理简化:可以更加轻松的管理较小的分区,包括备份、恢复、数据加载和删除等操作,此外,还可以更方便地执行维护操作,如优化索引,重建分区等
3、数据保护和容错:通过将数据分散在多个分区中,即使某个分区发生故障,也可以保留其它分区数据的完整性和可用性
4、存储效率提升:可以将不同分区设置为不同的存储介质,例如将历史数据存储在较慢的磁盘上,而将当前数据存储在更快的固态驱动器上,从而提高存储效率
需要注意的是,表分区功能在MySQL的某些版本和存储引擎中有一些限制和差异,因此在使用表分区之前,请确保你的MySQL版本和存储引擎支持所需的分区功能。

二、表分区有哪几种方案? 如何实现

2.1 范围分区(Range Partitioning)

适合场景:

1、创建订单表

CREATE TABLE order_payments (
    payment_id INT PRIMARY KEY, #支付编号
    order_id INT, #订单编号
    payment_date DATETIME, #支付日期
    payment_amount DECIMAL(10, 2), #支付金额
    payment_method VARCHAR(50), #支付方式
    card_number VARCHAR(50), #信用卡号码
    card_expiry_date DATETIME, #信用卡到期日期
    payment_status VARCHAR(20) #支付状态);

执行结果如下:
1.png

2、添加订单的索引为联合索引(需要修改为索引联合索引,不然后面会报错)

ALTER TABLE `order_payments` DROP PRIMARY KEY,ADD PRIMARY KEY (payment_id, order_id,payment_date);

执行结果如下:
1.png

3、按照订单时间范围来分区

ALTER TABLE order_payments
PARTITION BY RANGE(TO_SECONDS(payment_date))
(
  PARTITION p2023q1 VALUES LESS THAN (TO_SECONDS('2023-04-01 00:00:00')),
  PARTITION p2023q2 VALUES LESS THAN (TO_SECONDS('2023-07-01 00:00:00')),
  PARTITION p2023q3 VALUES LESS THAN (TO_SECONDS('2023-10-01 00:00:00')),
  PARTITION p2023q4 VALUES LESS THAN (TO_SECONDS('2024-01-01 00:00:00')),
  PARTITION p2024q1 VALUES LESS THAN (TO_SECONDS('2024-04-01 00:00:00')),
  PARTITION p2024q2 VALUES LESS THAN (TO_SECONDS('2024-07-01 00:00:00')),
  PARTITION p2024q3 VALUES LESS THAN (TO_SECONDS('2024-10-01 00:00:00')),
  PARTITION p2024q4 VALUES LESS THAN (TO_SECONDS('2025-01-01 00:00:00'))
);

执行结果如下:
1.png

4、向数据库插入数据(创建存储过程,循环插入2023到2025年的数据,数据时间间隔为半个小时1次)

备注:这一步也可以自行造2023年到2024年的数据测试

CREATE DEFINER=`root`@`localhost` PROCEDURE `insert_data`()
BEGIN
    DECLARE start_date DATETIME DEFAULT '2023-01-01 00:00:00';
    DECLARE end_date DATETIME DEFAULT '2025-01-01 00:00:00';
    DECLARE order_id INT DEFAULT 1;
    DECLARE payment_id INT;
    DECLARE payment_date DATETIME;

    SET payment_id = (order_id * 10) + 1;

    WHILE order_id <= 10000 DO
        SET payment_date = start_date;

        WHILE payment_date < end_date DO
            INSERT INTO test.order_payments (payment_id, order_id, payment_date, payment_amount, payment_method, card_number, card_expiry_date, payment_status)
            VALUES (payment_id, order_id, payment_date, RAND() * 1000, 'Credit Card', CONCAT('**** **** **** ', RIGHT(CAST(FLOOR(RAND() * POWER(10, 16)) AS CHAR), 4)), DATE_ADD(payment_date, INTERVAL 30 MINUTE), 'Paid');

            SET payment_id = payment_id + 1;
            SET payment_date = DATE_ADD(payment_date, INTERVAL 30 MINUTE);
        END WHILE;

        SET order_id = order_id + 1;
    END WHILE;
END

执行结果如下:
1.png
注意存储过程需要赋予权限,不然执行不了
1.png
最后执行存储过程执行一段时间,然后点击停止。
1.png

最后数据库数据如下图
1.png

5、查询分区数据插入情况

 SELECT PARTITION_NAME, PARTITION_EXPRESSION, PARTITION_DESCRIPTION, TABLE_ROWS
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME = 'order_payments';

这里就是每一个分区的数据量
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/e337fb951804428a8e861e664bf060a1.png1.png

6、根据分区查询数据

#只查询2023年三季度的数据

select * from order_payments partition(p2023q3)

如下图
1.png

猜你喜欢

【MySQL】MySql中的锁(表锁,行锁)
&nbsp; &nbsp; 锁是计算机协调多个进程或纯线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所在有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。&nbsp;概述&nbsp; &nbsp; 相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。My
发表于:2024-06-16 浏览:243 TAG:
【MySql】SELECT* 会导致查询效率低的原因
前言一、适合SELECT*的使用场景二、SELECT*会导致查询效率低的原因2.1、数据库引擎的查询流程2.2、SELECT*的实际执行过程2.3、使用SELECT*查询语句带来的不良影响三、优化查询...
发表于:2024-10-21 浏览:303 TAG: #mysql
【MySQL】数据操作
一、数据操作介绍#在MySQL管理软件中,可以通过SQL语句中的DML语言来实现数据的操作1.INSERT实现数据的插入2.UPDATE实现数据的更新3.DELETE实现数据的删除4.SELECT查询数据&nbsp;二、插入数据  #语法一:&nbsp;按字段进行插入 insert&nbsp;into&nbsp;表(字段1,字段2&nbsp;...)&nbsp;values&nbsp;(值1,值2&nbsp;...); &nbsp; 二:按字段顺序插入 insert&nbsp;into&amp;nbs
发表于:2024-06-21 浏览:311 TAG: #mysql
【MySQL】 复合查询 | 内外连接
文章目录1. 复合查询unionunion all单行子查询多行子查询多列子查询in关键字all关键字any关键字多表笛卡尔积自连接在where子句使用子查询在from子句中使用子查询合并查询2. 内连接3. 外连接左外连接右外连接1. 复合查询多表笛卡尔积显示雇员名、雇员工资以及所在部门的名字由于员工 信息属于 emp表 而所在部门名字属于 dept表 数据来自不同的表,所以需要进行多表查询表示从 emp (员工表) 和dept (部门表)
发表于:2023-11-30 浏览:872 TAG:
【MySQL】MySQL索引原理与慢查询优化
浏览目录#&nbsp;一、索引介绍二、索引方法三、索引类型四、聚合索引和辅助索引五、测试索引六、正确使用索引七、组合索引八、注意事项九、查询计划十、慢日志查询十一、大数据量分页优化一、索引介绍#  一般的应用系统,读写的比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出现问题的,还是一些复杂的查询操作,因此对查询语句的优化显然是重中之重。什么是索引:简单来说,相当于图书的目录,可以帮助用户快速找到需要的内容。&nbsp;  在mysql中
发表于:2024-06-21 浏览:385 TAG:
【MySql】select * 查询慢的原因和优化方法
&zwnj;使用SELECT&nbsp;*查询语句会导致查询效率低下的原因主要包括&zwnj;:它会查询所有的列和行数据,包括不需要的和重复的列,因此会占用更多的系统资源,导致查询效率低下。此外,由于...
发表于:2024-10-21 浏览:277 TAG: #mysql
【MySQL】MySQL数据库CPU飙升到100%解决方案
1、定位cpu问题所在当cpu飙升到100%时,先用操作系统命令top命令观察是不是mysqld占用导致的,如果不是,找出占用高的进程,并进行相关处理。2、查看慢查询日志进入mysql命令行mysql&nbsp;-h主机地址&nbsp;-u用户名&nbsp;-p用户密码1查看慢查询SQL是否启用:ON是开启,OFF是关闭。 show variables like ‘log_slow_queries’;开启慢查询日志 set global log_slow_queries = on;3、使用sho
发表于:2024-07-17 浏览:253 TAG:
【MySql】mysql 将数据库中的所有表结构和数据 导入到另一个库(亲测有效)
一、问题描述在本地开发一个功能,需要结合具体数据测试代码是否正确,但服务器上的数据不可随便修改。此时则需要将服务器上某个数据库的表批量导入到本地、而后进行测试。将数据库db1中的所有表及数据(如table1、table2),批量导入到另一个数据库db2中。二、解决方案刚开始自己一直尝试用DataGrip、Navicat的sql/csv格式导入导出,总有错误或者遗漏,比如报错中止、50张表却只导入32张等,可能是操作方式有误或者数据格式有问题。也试过用sql语句,但仍失败。经查阅资料、尝试多次,终
发表于:2024-01-30 浏览:380 TAG:
【MySQL】MySQL 之 视图、触发器、存储过程、函数、事物与数据库锁
一、视图#视图是一个虚拟表(非真实存在的),其本质是‘根据SQL语句获取动态的数据集,并为其命名‘ ,用户使用时只需使用“名称”即可获取结果集,可以将该结果集当做表来使用。使用视图我们可以把查询过程中的临时表摘出来,用视图去实现,这样以后再想操作该临时表的数据时就无需重写复杂的SQL了,直接去视图中查找即可,但视图有明显的效率问题,并且视图是存放在数据库中的,如果我们程序中使用的SQL过分依赖数据库中的视图,即强耦合,那就意味着扩展SQL极为不便,因此并不推荐使用视图有如下的特点:&nbsp;&amp;
发表于:2024-06-21 浏览:315 TAG:
【MySql】MySql给数据库表添加新字段
要在MySQL中添加新字段,您可以使用ALTER TABLE语句。以下是添加新字段的基本语法:ALTER&nbsp;TABLE&nbsp;table_name&nbsp;ADD&nbsp;column_name&nbsp;datatype;其中:table_name 是您要在其中添加新字段的表的名称。column_name 是新字段的名称。datatype 是新字段的数据类型。例如,VARCHAR、INT或DOUBLE等。以下是一个示例ALTER TABLE语句,演示如何向名为user的表添加一
发表于:2024-09-03 浏览:247 TAG: #mysql