首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按日期划分非常大的表- MySQL

按日期划分非常大的表- MySQL
EN

Stack Overflow用户
提问于 2015-06-29 12:02:47
回答 1查看 2.8K关注 0票数 2

我希望在MySQL中的日期格式列上创建一个带有分区的表,并希望每次添加额外的日期(每天)时更新分区。

对此最好的方法是什么?用于此的代码是什么?

提前感谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-29 13:27:42

如果我们举一个简单的例子:

代码语言:javascript
复制
CREATE TABLE `test`.`NewTable` (
 `id` INT NOT NULL AUTO_INCREMENT,
 `created` DATETIME NULL,
 PRIMARY KEY (`id`,`created`)
);

ALTER TABLE `test`.`NewTable`
PARTITION BY RANGE (TO_DAYS(`Created`)) (
 PARTITION `20150531` VALUES LESS THAN (TO_DAYS('2015-06-01 00:00:00')),
 PARTITION `20150601` VALUES LESS THAN (TO_DAYS('2015-06-02 00:00:00')),
 PARTITION `20150602` VALUES LESS THAN MAXVALUE
);

这为您提供了一个具有三个分区的表:

20150531 =6月1日前的所有旧数据

20150601 =6月1日起的所有数据

20150602 =6月1日以后的所有未来数据(或带有不正确的未来时间戳)

在6月2日开始时,您希望创建一个新的分区,该分区将保存6月2日的所有数据。要做到这一点,您需要将20150602分区分成两个分区。

6月2日所有数据的20150602

20150603用于6月2日以后的所有未来数据(或带有不正确的未来时间戳)

这是通过以下方式完成的:

代码语言:javascript
复制
ALTER TABLE `test`.`NewTable` 
REORGANIZE PARTITION 20150602 INTO (
 PARTITION 20150602 VALUES LESS THAN (TO_DAYS('2015-06-03 00:00:00')),  
 PARTITION 20150603 VALUES LESS THAN MAXVALUE
); 

这样,您就可以使用:

代码语言:javascript
复制
SELECT MAX(PARTITION_NAME) FROM INFORMATION_SCHEMA.partitions
WHERE TABLE_SCHEMA = 'test' 
AND TABLE_NAME = 'NewTable';

为了得到您未来的分区,从那里,应该很简单地确定下一个分区需要是什么。

我所使用的事件:

代码语言:javascript
复制
DROP EVENT AddNewPartition_daily;
DELIMITER $$
CREATE EVENT AddNewPartition_daily
ON SCHEDULE
EVERY 1 DAY STARTS CONCAT(DATE_SUB(CURDATE(), INTERVAL -1 DAY),' 00:00:01')
ON COMPLETION PRESERVE
COMMENT 'Adds a New Partition to the Top, and Removes the Oldest Partition From NewTable'
DO
BEGIN
SET @MinP := (SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 9 DAY),'%Y%m%d'));
SET @MaxP := (SELECT MAX(PARTITION_NAME) FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME = 'NewTable');

SET @Today := (SELECT CONCAT(CURDATE(),' 00:00:00'));
SET @Tomorrow := (SELECT CONCAT(DATE_SUB(CURDATE(), INTERVAL -1 DAY),' 00:00:00'));

SET @TodP := (SELECT DATE_FORMAT(CURDATE(),'%Y%m%d'));
SET @TomP := (SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL -1 DAY),'%Y%m%d'));

#ADD NEW PARTITION TO TOP
SET  @SQL1 := CONCAT('
ALTER TABLE test.NewTable
REORGANIZE PARTITION `',@TodP,'` INTO
(
    PARTITION `',@TodP,'` VALUES LESS THAN (TO_DAYS(\'',@Tomorrow,'\')),
    PARTITION `',@TomP,'` VALUES LESS THAN MAXVALUE
)');

     PREPARE stmt FROM @SQL1;
     EXECUTE stmt;
     DEALLOCATE PREPARE stmt;

#REMOVE OLDEST PARTITION
SET @SQL2 := CONCAT('ALTER TABLE test.NewTable DROP PARTITION `',@MinP,'`');  

PREPARE stmt FROM @SQL2;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

END $$
DELIMITER ;

您应该注意到,如果您只是不断地添加分区而不删除分区,那么最终会影响性能。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31115206

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档