Mysql按天自动表分区教程

前言

在使用mysql时,往往用一张表来存放数据,不同的业务可能产生的数据量也不同,有的业务可能一天需要插入几万条数据,也有的则更多,即使量很小日积月累数据库表的数据堆积也会越来越多,需要人工去删除数据,当数据达到百万或千万级别时,mysql查询速度明显下降,性能也随之下降,解决该问题的办法有很多,比如添加索引、优化SQL,但这都只是治标不治本的做法,无法从根本上提高Mysql的性能和查询速度。

什么是表分区?

mysql数据库中的数据是以文件的形势存在磁盘上的,默认放在/mysql/data下面(可以通过my.cnf中的datadir来查看),一张表主要对应着三个文件,一个是frm存放表结构的,一个是myd存放表数据的,一个是myi存表索引的。如果一张表的数据量太大的话,那么myd,myi就会变的很大,查找数据就会变的很慢,这个时候我们可以利用mysql的分区功能,在物理上将这一张表对应的三个文件,分割成许多个小块,这样呢,我们查找一条数据时,就不用全部查找了,只要知道这条数据在哪一块,然后在那一块找就行了。如果表的数据太大,可能一个磁盘放不下,这个时候,我们可以把数据分配到不同的磁盘里面去。

表分区,是指根据一定规则,将数据库中的一张表分解成多个更小的,容易管理的部分。从逻辑上看,只有一张表,但是底层却是由多个物理分区组成。

创建测试表

CREATE TABLE `dcdlqx` (
  `u_time` int(11) NOT NULL COMMENT '采集时间',
  `zh_order` tinyint(4) NOT NULL COMMENT '道岔方向',
  KEY `index_utime` (`u_time`) USING BTREE
) ENGINE=MyISAM CHARSET=utf8 ROW_FORMAT=COMPRESSED COMMENT='道岔电流曲线';

手动进行分区

对自动分区的表必须是在该表有手动分区的前提之下才能进行; 对以下代码稍做解释,less than 的意思是小于的意思,所以p20230919这个分区里面存放的数据都是比2023年09月19日之前的数据,以此类推,p20230920存放的是09月20日的数据。

命令说明#单条增加分区

ALTER TABLE dcdlqx ADD PARTITION (PARTITION p20230919 VALUES LESS THAN(UNIX_TIMESTAMP('2023-09-19')));

命令说明#删除分区命令

ALTER TABLE dcdlqx DROP PARTITION p20230919;

命令说明#查看表分区

SELECT * FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA=SCHEMA() AND TABLE_NAME='dcdlqx';
PARTITION_NAME	PARTITION_DESCRIPTION
p20230918	    1695052800
p20230919	    1695139200

分区维护#自动按天分表函数

说明:该函数可以按天新增分区,删除历史分区(保留指定天数的分区,超出部分自动删除)

DROP PROCEDURE IF EXISTS proc_partiontable_byday;

DELIMITER $$
CREATE PROCEDURE `proc_partiontable_byday`(
	IN tablename VARCHAR (50), -- 表名称
	IN keepday INT, -- 分区保留天数
	OUT msg VARCHAR (100)) -- 输出日志 @msg
BEGIN

DECLARE pMinValue INT DEFAULT UNIX_TIMESTAMP(DATE_SUB(CURDATE(),INTERVAL keepday DAY));-- 在这时间之前的分区需要删除
DECLARE ptoday VARCHAR(9) DEFAULT CONCAT('p',DATE_FORMAT(DATE_ADD(CURDATE(),INTERVAL 1 DAY), '%Y%m%d'));-- 今天分区名称
DECLARE ptomorrow VARCHAR(9) DEFAULT CONCAT('p',DATE_FORMAT(DATE_ADD(CURDATE(),INTERVAL 2 DAY), '%Y%m%d'));-- 明天分区名称

DECLARE pQMinValue INT DEFAULT UNIX_TIMESTAMP();-- 查得最早分区时间
DECLARE pQMinName VARCHAR(9) DEFAULT '';-- 查得最早分区名称
DECLARE pQtoday VARCHAR(9) DEFAULT '';-- 查得今日分区
DECLARE pQtomorrow VARCHAR(9) DEFAULT '';-- 查得明日分区

SELECT
MIN(PARTITION_DESCRIPTION),
MAX(CASE PARTITION_ORDINAL_POSITION WHEN 1 THEN PARTITION_NAME ELSE '' END),
MAX(CASE PARTITION_NAME WHEN ptoday THEN PARTITION_NAME ELSE '' END),
MAX(CASE PARTITION_NAME WHEN ptomorrow THEN PARTITION_NAME ELSE '' END )
INTO pQMinValue,pQMinName,pQtoday,pQtomorrow 
FROM information_schema.PARTITIONS 
WHERE TABLE_SCHEMA=SCHEMA() AND TABLE_NAME=tablename;

SET msg = CONCAT('分区维护:',tablename,'[');

-- 创建今日分区
IF pQtoday = ptoday THEN
   SET msg=CONCAT(msg,'已存在:',ptoday);
ELSE
   SET @psql = CONCAT('ALTER TABLE ',tablename ,' ADD PARTITION(PARTITION ',ptoday, ' VALUES LESS THAN(',UNIX_TIMESTAMP(DATE_ADD(CURDATE(),INTERVAL 1 DAY)), '));');
   PREPARE stmt from @psql;
   EXECUTE stmt;
   DEALLOCATE PREPARE stmt;
	 SET msg=CONCAT(msg,'已创建:',ptoday);
END IF;
 
-- 创建明日分区
IF pQtomorrow = ptomorrow THEN
   SET msg=CONCAT(msg,'已存在:',ptomorrow);
ELSE
   SET @psql = CONCAT('ALTER TABLE ',tablename ,' ADD PARTITION(PARTITION ',ptomorrow, ' VALUES LESS THAN(',UNIX_TIMESTAMP(DATE_ADD(CURDATE(),INTERVAL 2 DAY)), '));');
   PREPARE stmt from @psql;
   EXECUTE stmt;
   DEALLOCATE PREPARE stmt;
	 SET msg=CONCAT(msg,'已创建:',ptomorrow);
END IF;

-- 删除历史分区
IF pQMinValue < pMinValue THEN
   SET @psql = CONCAT('ALTER TABLE ', tablename, ' DROP PARTITION ',pQMinName,';');
   PREPARE stmt from @psql;
   EXECUTE stmt;
   DEALLOCATE PREPARE stmt;
	 SET msg=CONCAT(msg,'删除分区:',pQMinName);
END IF;

SET msg=CONCAT(msg,']');

END
$$
DELIMITER;

分区维护#自动按天分表事件

DROP EVENT Event_partiontable_byday;
SET GLOBAL event_scheduler = ON;
DELIMITER $$
CREATE EVENT IF NOT EXISTS Event_partiontable_byday
ON SCHEDULE EVERY 1 DAY STARTS CURRENT_TIMESTAMP -- 每1天执行一次检查分区
ON COMPLETION PRESERVE
DO
BEGIN
CALL proc_partiontable_byday('dcdlqx',3,@msg);
SELECT @msg;
END
$$
DELIMITER ;
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
├─新版MySQL DBA 课件ppt │ 第一课数据库介绍篇.pdf │ 第七课MySQL数据库设计.pdf │ 第三十一课percona-toolkits 的实战及自动化.pdf │ 第三课MySQL授权认证.pdf │ 第九课MySQL字符集.pdf │ 第二十一课MySQL常见错误-converted.pdf │ 第二十课MySQL索引和调优.pdf │ 第二课MySQL入门介绍.pdf │ 第五课MySQL常用函数介绍.pdf │ 第八课InnoDB内核.pdf │ 第六课SQL高级应用.pdf │ 第十一课MySQL分区8.0.pdf │ 第十七课Elasticsearch分享-张亚V4.pdf │ 第十三课MySQL5.7高可用架构之Mycat.pdf │ 第十三课MySQL8.0高可用架构之Mycat.pdf │ 第十九课MySQL备份和恢复.pdf │ 第十二课MySQL5.7复制.pdf │ 第十二课MySQL8.0复制.pdf │ 第十五课MySQL8.0高可用架构之MHA和MMM.pdf │ 第十五课MySQL高可用架构之MHA和MMM.pdf │ 第十八课mongo分享-张亚V1.pdf │ 第十六课Redis分享-张亚V2.pdf │ 第十四课MySQL8.0高可用架构之Atlas.pdf │ 第十课MySQL8.0锁机制和事务.pdf │ 第十课MySQL锁机制和事务.pdf │ 第四课SQL基础语法.pdf │ ├─新版MySQL DBA综合实战班 第01天 │ 0_MySQL高级DBA公开课视频.avi │ 1_数据库通用知识介绍.avi │ 2_MySQL8常规安装.avi │ 3_MySQL8非常规安装.avi │ 4_MySQL8常见客户端和启动相关参数.avi │ ├─新版MySQL DBA综合实战班 第02天 │ 10_MySQL Update课堂练习.mp4 │ 1_课后作业讲解.mp4 │ 2_MySQL权限系统介绍.mp4 │ 3_MySQL授权用户和权限回收.mp4 │ 4_MySQL8新的密码认证方式和客户端链接.mp4 │ 5_MySQL Create命令.mp4 │ 6_MySQL CreateTable命令.mp4 │ 7_课堂练习1.mp4 │ 8_MySQL Insert命令.mp4 │ 9_MySQL Insert课堂练习和Update命令.mp4 │ ├─新版MySQL DBA综合实战班 第03天 │ 1_课堂作业讲解.mp4 │ 2_MySQL Delete语法讲解.mp4 │ 3_MySQL Select语法讲解.mp4 │ 4_MySQL Select多连接讲解.mp4 │ 5_MySQL其他常用命令讲解.mp4 │ 6_MySQL操作符和常用函数.mp4 │ 7_MySQL常用字符串和日期函数.mp4 │ delete.txt │ MySQL高级DBA大作业1.docx │ 作业.docx │ ├─新版MySQL DBA综合实战班 第04天 │ 1_课后作业讲解.mp4 │ 2_SQL课堂强化练习1.mp4 │ 3_SQL课堂强化练习2.mp4 │ 4_存储过程函数概念和创建讲解.mp4 │ 5_存储过程函数流程控制语句讲解.mp4 │ ├─新版MySQL DBA综合实战班 第05天 │ 1_课后作业讲解.mp4 │ 2_MySQL游标讲解.mp4 │ 3_MySQL触发器.mp4 │ 4_MySQL触发器课堂强化练习.mp4 │ 5_MySQL数字和时间类型.mp4 │ 6_MySQL字符串类型.mp4 │ 7_MySQL存储引擎.mp4 │ 8_MySQL第三范式设计讲解.mp4 │ 9_MySQL数据库设计工具.mp4 │ ├─新版MySQL DBA综合实战班 第06天 │ 1_课堂作业讲解.mp4 │ 2_InnoDB内核之事务和多版本控制.mp4 │ 3_InnoDB底层文件存储和体系结构.mp4 │ 4_InnoDB体系结构.mp4 │ 5_InnoDB存储引擎配置.mp4 │ 6_InnoDB统计资料和其他配置.mp4 │ 7_InnoDB锁原理和锁等待问题定位.mp4 │ ├─新版MySQL DBA综合实战班 第07天 │ 1_课后作业讲解.mp4 │ 2_MySQL锁机制原理讲解.mp4 │ 3_MySQL锁相关参数设置.mp4 │ 4_InnoDB事务隔离级别详解.mp4 │ 5_InnoDB死锁发生原理和规避.mp4 │ 6_MySQL字符集和排序规则.mp4 │ 作业.docx │ 锁等待分析.txt │ ├─新版MySQL DBA综合实战班 第08天 │ 1_课堂作业讲解.mp4 │ 2_MySQL乱码原理讲解.mp4 │ 3_MySQL排序规则权重.mp4 │ 4_MySQL字符集空间消耗.mp4 │ 5_MySQL分区介绍和优势.mp4 │ 6_MySQL分区类型.mp4 │ 7_MySQL分区和NULL值特殊处理.mp4 │ 8_MySQL分区管理.mp4 │ 作业.docx │ 作业及答案.docx │ ├─新版MySQL DBA综合实战班 第09天 │ 1_课堂作业讲解.mp4 │ 2_MySQL复制原理.mp4 │ 3_MySQL传统复制原理和搭建.mp4 │ 4_MySQL复制搭建part2.mp4 │ 5_MySQL复制相关参数.mp4 │ 6_MySQL复制状态和延迟复制.mp4 │ 7_MySQL半同步复制.mp4 │ 作业.docx │ ├─新版MySQL DBA综合实战班 第10天 │ │ 1_课后作业讲解.mp4 │ │ 2_MySQL传统复制手动切换和GTID复制原理及切换.mp4 │ │ 3_Mycat原理和schema配置讲解.mp4 │ │ 4_Mycat schema配置讲解.mp4 │ │ 5_Mycat企业高可用配置.mp4 │ │ 作业.docx │ │ │ └─MySQL DBA 课堂命令-复制和Mycat │ mysql-master.log │ mysql-master2.log │ mysql-mycat.log │ mysql-slave1.log │ mysql-slave2.log │ ├─新版MySQL DBA综合实战班 第11天 │ │ 1_课后作业讲解.mp4 │ │ 2_MyCat分库分原理和常见方法.mp4 │ │ 3_MyCat管理操作.mp4 │ │ 4_Atlas配置和读写分离实现.mp4 │ │ 5_Atlas分库分实现.mp4 │ │ 6_MHA搭建和故障切换原理剖析.mp4 │ │ │ └─MySQL DBA_课堂命令-Mycat和Atlas和MHA │ mysql-master.log │ mysql-mycat.log │ mysql-slave1.log │ mysql-slave2.log │ ├─新版MySQL DBA综合实战班 第12天 │ 01ES介绍.docx │ 01es介绍.mp4 │ 01redis介绍.mp4 │ 02es增删改查操作命令.mp4 │ 02ES的功能适用场景以及特点介绍.docx │ 02redis应用场景.mp4 │ 03ES的核心概念.docx │ 03redis单实例安装.mp4 │ 03集群分片副本操作.mp4 │ 04es集群运维.mp4 │ 04redis数据类型操作.mp4 │ 04安装search-guard.docx │ 05redis主从和哨兵操作.mp4 │ 06reids集群创建收缩扩容.mp4 │ 07redis运维工具.mp4 │ Elasticsearch分享V2.pdf │ Elasticsearch分享V4.pdf │ ES分享试验环境.docx │ ES操作.txt │ Redis分享-张亚V2.pdf │ 日志收集.txt │ 监控和分词.txt │ 防脑裂配置.txt │ ├─新版MySQL DBA综合实战班 第13天-mongo │ 01mongo介绍.mp4 │ 02mongo安装配置优化.mp4 │ 03mongo增删改查.mp4 │ 04授权认证和索引.mp4 │ 05mongo常用工具介绍.mp4 │ 06mongo副本集升级备份恢复.mp4 │ 07ELK模板收集mongo日志.mp4 │ mongodb.jpg │ Mongodb分享-贾海娇.pdf │ mongo数据库分享-张亚V1.pdf │ monogdb.conf │ ├─新版MySQL DBA综合实战班 第14天 │ │ 1_MHA手工切换和GTID支持.mp4 │ │ 2_MMM高可用架构.mp4 │ │ 3_MySQL备份概念.mp4 │ │ 4_Mysqldump备份原理.mp4 │ │ 5_Mysqldump基于备份.mp4 │ │ 6_MySQL全量恢复和日志增量恢复.mp4 │ │ 7_xtrabackup全量和增量备份恢复.mp4 │ │ 作业及答案.docx │ │ │ └─MySQL DBA堂命令-mha和备份恢复 │ mysql-master_05-18_10-03-09.log │ mysql-master_05-18_14-02-01.log │ mysql-mycat_05-18_10-03-02.log │ mysql-slave1_05-18_10-03-14.log │ mysql-slave2_05-18_10-03-20.log │ ├─新版MySQL DBA综合实战班 第15天 │ │ 1_课后作业讲解.mp4 │ │ 2_MySQL索引原理介绍.mp4 │ │ 3_MySQL索引类型介绍.mp4 │ │ 4_MySQL索引底层结构和执行计划.mp4 │ │ 5_MySQL索引优化原则.mp4 │ │ 6_MySQL运维常见错误part1.mp4 │ │ 7_MySQL运维常见错误part2.mp4 │ │ ERROR1040_1917970.1.pdf │ │ ERROR1062_1593526.1.pdf │ │ ERROR1205_1911871.1.pdf │ │ ERROR2002_1023190.1.pdf │ │ How_to_Reset_the_RootPassword.pdf │ │ How_to_Reset_the_RootPassword5.7.pdf │ │ PacketTooLarge.pdf │ │ │ └─MySQL DBA课堂命令-索引调优和运维常见错误 │ mysql-master-05-25_11-10-39.log
好的,我可以为您解答这个问题。 MySQL分区可以提高查询性能,并且可以通过按时间范围进行自动分区,以便更好地管理和维护数据。下面是按天执行分区SQL的步骤: 1. 创建分区 您可以使用以下命令创建一个按天分区: ``` CREATE TABLE mytable ( id INT NOT NULL, created_at TIMESTAMP NOT NULL ) PARTITION BY RANGE(TO_DAYS(created_at)) ( PARTITION p0 VALUES LESS THAN (TO_DAYS('2022-01-01')), PARTITION p1 VALUES LESS THAN (TO_DAYS('2022-01-02')), PARTITION p2 VALUES LESS THAN (TO_DAYS('2022-01-03')), ... PARTITION pn VALUES LESS THAN MAXVALUE ); ``` 这将创建一个名为“mytable”的分区,其中“created_at”列将用于分区分区按天进行。您需要为每个分区指定值范围,例如“p0”分区包含所有在“2022-01-01”之前创建的记录。 2. 创建分区维护事件 您可以创建一个事件,定期检查并创建新的分区。以下是一个示例事件: ``` CREATE EVENT partition_maintenance ON SCHEDULE EVERY 1 DAY DO ALTER TABLE mytable ADD PARTITION ( PARTITION pmax VALUES LESS THAN MAXVALUE ); ``` 这将创建一个名为“partition_maintenance”的事件,每天运行一次,它将在“mytable”中创建一个新的分区。 3. 自动分区 您可以在中插入数据时自动创建分区。以下是一个示例触发器: ``` CREATE TRIGGER partition_insert BEFORE INSERT ON mytable FOR EACH ROW BEGIN DECLARE partition_name VARCHAR(20); SET partition_name = CONCAT('p', DATE_FORMAT(NEW.created_at, '%Y%m%d')); SET @partition_sql = CONCAT('PARTITION ', partition_name, ' VALUES LESS THAN (TO_DAYS(\'', DATE_ADD(DATE(NEW.created_at), INTERVAL 1 DAY), '\'))'); SET @sql = CONCAT('ALTER TABLE mytable ADD ', @partition_sql); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END; ``` 这将创建一个名为“partition_insert”的触发器,在插入新记录时自动创建新的分区。该触发器将使用新记录的“created_at”值计算分区名称,并为该名称创建一个新的分区。 总之,以上是按天执行分区SQL的步骤,希望对您有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值