【问题标题】:Partition very large table by date - MySQL按日期对非常大的表进行分区 - MySQL
【发布时间】:2015-06-29 12:02:47
【问题描述】:

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

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

提前致谢

【问题讨论】:

  • 我在这里做同样的事情,在每天开始时使用计划事件来添加新分区,并删除最旧的分区。
  • 感谢 IGGt 如何将分区添加到现有表的分区列表中?
  • 见下文,希望对您有所帮助。
  • 为什么你认为这是对数据进行分区的正确方法?

标签: mysql sql database mysql-workbench


【解决方案1】:

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

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 日之前的所有 [OLD] 数据
20150601 = 6 月 1 日之后的所有数据
20150602 = 6 月 1 日之后的所有 [FUTURE] 数据(或未来时间戳不正确)

在 6 月 2 日开始时,您想创建一个新分区来保存 6 月 2 日的所有数据。 为此,您需要将20150602 分区分成两个分区。

20150602 表示 6 月 2 日的所有数据
20150603 表示 6 月 2 日之后的所有 [FUTURE] 数据(或未来时间戳不正确)

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

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
); 

这样你就可以使用了:

SELECT MAX(PARTITION_NAME) FROM INFORMATION_SCHEMA.partitions
WHERE TABLE_SCHEMA = 'test' 
AND TABLE_NAME = 'NewTable';

获取您的 FUTURE 分区,并从那里直接计算出下一个分区需要是什么。

我为此使用的事件:

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 ;

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

【讨论】:

    猜你喜欢
    • 2020-04-29
    • 2012-02-16
    • 2016-02-21
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 2016-10-15
    • 1970-01-01
    • 2016-07-07
    相关资源
    最近更新 更多