mysql : range分区、range和key复合分区、分区裁剪

--##test01大小为52G,保存大概两天的数据
--##每天数据大约25G左右,每天需创建一张备份表,插入新一天的数据,再要在这张表中删除前一天的数据
--##现在采取分区裁剪的办法,避免多余的备份与删除
--##现在分区分为两种:
--##1.简单range分区(一层分区,每个区大约25G)
--##2.range和key复合分区(两层分区,理想状态下均匀分布每个分区大概3G,但从实际历史表分区情况看,数据分布不均匀)
--##


--#########################################
--#############range分区###################
--1.停止应用服务器,杀死所有连接进程
--2.重命名大表
ALTER TABLE test01 RENAME TO risk_result_terminal_real20180620;
--3.创建分区表
 CREATE TABLE `test01` (
  `ResultID` VARCHAR(40) NOT NULL COMMENT '机场4字码',
  `NodeId` VARCHAR(40) NOT NULL COMMENT '终端风险因素ID',
  `RiskValue` DOUBLE(5,2) DEFAULT '1.00' COMMENT '终端风险因素值',
  `ComputeTime` DATETIME DEFAULT NULL COMMENT '计算时间',
  `Description` VARCHAR(500) DEFAULT NULL COMMENT '得分备注',
  `Sort` INT(11) DEFAULT NULL,
  `Dimension` VARCHAR(50) DEFAULT NULL COMMENT '评分维度',
  `ItemId` VARCHAR(40) DEFAULT NULL COMMENT '航班ID',
  KEY `r_resultid` (`ResultID`),
  KEY `r_itemId` (`ItemId`),
  KEY `r_risktime` (`ComputeTime`),
  KEY `r_NodeId` (`NodeId`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
/*!50500 PARTITION BY RANGE  COLUMNS(ComputeTime)
(PARTITION p20180621 VALUES LESS THAN ('2018-06-22') ENGINE = InnoDB,
 PARTITION p20180622 VALUES LESS THAN ('2018-06-23') ENGINE = InnoDB,
 PARTITION p20180623 VALUES LESS THAN ('2018-06-24') ENGINE = InnoDB,
 PARTITION p20180624 VALUES LESS THAN ('2018-06-25') ENGINE = InnoDB,
 PARTITION p20180625 VALUES LESS THAN ('2018-06-26') ENGINE = InnoDB,
 PARTITION p20180626 VALUES LESS THAN ('2018-06-27') ENGINE = InnoDB,
 PARTITION p20180627 VALUES LESS THAN ('2018-06-28') ENGINE = InnoDB) */
--#修改代码
--分区增加
ALTER TABLE test01 ADD PARTITION (PARTITION p20160524 VALUES LESS THAN ('2018-06-25'));
--分区裁剪
ALTER TABLE test01 DROP PARTITION p20180621;




--#创建存储过程,调用实现分区裁剪;
DELIMITER $$
USE `mrvc`$$
DROP PROCEDURE IF EXISTS `create_Partition`$$

CREATE DEFINER=`root`@`%` PROCEDURE `create_Partition`()
BEGIN
/* 事务回滚,其实放这里没什么作用,ALTER TABLE是隐式提交,回滚不了的。*/
DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
START TRANSACTION;

/* 到系统表查出这个表的最大分区,得到最大分区的日期。在创建分区的时候,名称就以日期格式存放,方便后面维护 */
SELECT REPLACE(partition_name,'p','') INTO @date_num FROM INFORMATION_SCHEMA.PARTITIONS
WHERE table_name='test01' ORDER BY partition_ordinal_position DESC LIMIT 1;
SET @Next_date= DATE(DATE_ADD(@date_num+0, INTERVAL 1 DAY))+0;
SET @Max_date= DATE(DATE_ADD(@date_num+0, INTERVAL 2 DAY))+0;

/* 修改表,在最大分区的后面增加一个分区,时间范围加1天 */
SET @s1=CONCAT('ALTER TABLE test01 ADD PARTITION (PARTITION p',@Next_date,' VALUES LESS THAN (''',DATE(@Max_date),'''))');

/* 输出查看增加分区语句
SELECT @s1;*/
PREPARE stmt2 FROM @s1;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt2;

 /* 取出最小的分区的名称,并删除掉 。
    注意:删除分区会同时删除分区内的数据,慎重 */
SELECT partition_name INTO @first_num FROM INFORMATION_SCHEMA.PARTITIONS
WHERE table_name='test01' ORDER BY partition_ordinal_position LIMIT 1;
SET @s=CONCAT('ALTER TABLE test01 DROP PARTITION ',@first_num);
/* 输出查看增加分区语句
SELECT @s;*/
PREPARE stmt1 FROM @s;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
COMMIT;
END$$
DELIMITER ;

--#调用方法#
--方法一
--###应用程序调用存储过程
 CALL mrvc.`create_Partition`;  
 
--方法二
--###mysql定时事件执行存储过程
DELIMITER ;
DELIMITER $$
CREATE EVENT Partition_risk_event  
          ON SCHEDULE  
          EVERY 1 day STARTS '2016-05-22 02:00:00'   
          DO  
      BEGIN  

          CALL mrvc.`create_Partition`;  
        
END $$
DELIMITER ;




--######################################################
--#############range和key构成复合分区###################
--1.停止应用服务器,杀死所有连接进程
--2.重命名大表
ALTER TABLE test01 RENAME TO risk_result_terminal_real20180620;
--3.创建分区表
SHOW CREATE TABLE test01;
CREATE TABLE `test01` (
  `ResultID` VARCHAR(40) NOT NULL COMMENT '机场4字码',
  `NodeId` VARCHAR(40) NOT NULL COMMENT '终端风险因素ID',
  `RiskValue` DOUBLE(5,2) DEFAULT '1.00' COMMENT '终端风险因素值',
  `ComputeTime` DATETIME DEFAULT NULL COMMENT '计算时间',
  `Description` VARCHAR(500) DEFAULT NULL COMMENT '得分备注',
  `Sort` INT(11) DEFAULT NULL,
  `Dimension` VARCHAR(50) DEFAULT NULL COMMENT '评分维度',
  `ItemId` VARCHAR(40) DEFAULT NULL COMMENT '航班ID',
  KEY `r_resultid` (`ResultID`),
  KEY `r_itemId` (`ItemId`),
  KEY `r_risktime` (`ComputeTime`),
  KEY `r_NodeId` (`NodeId`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
/*!50500 PARTITION BY RANGE  COLUMNS(ComputeTime)
SUBPARTITION BY LINEAR KEY (ItemId)
(PARTITION p20180621 VALUES LESS THAN ('2018-06-22')
 (SUBPARTITION p201806210 ENGINE = InnoDB,
  SUBPARTITION p201806211 ENGINE = InnoDB,
  SUBPARTITION p201806212 ENGINE = InnoDB,
  SUBPARTITION p201806213 ENGINE = InnoDB,
  SUBPARTITION p201806214 ENGINE = InnoDB,
  SUBPARTITION p201806215 ENGINE = InnoDB,
  SUBPARTITION p201806216 ENGINE = InnoDB,
  SUBPARTITION p201806217 ENGINE = InnoDB,
  SUBPARTITION p201806218 ENGINE = InnoDB,
  SUBPARTITION p201806219 ENGINE = InnoDB),
 PARTITION p20180622 VALUES LESS THAN ('2018-06-23')
 (SUBPARTITION p201806220 ENGINE = InnoDB,
  SUBPARTITION p201806221 ENGINE = InnoDB,
  SUBPARTITION p201806222 ENGINE = InnoDB,
  SUBPARTITION p201806223 ENGINE = InnoDB,
  SUBPARTITION p201806224 ENGINE = InnoDB,
  SUBPARTITION p201806225 ENGINE = InnoDB,
  SUBPARTITION p201806226 ENGINE = InnoDB,
  SUBPARTITION p201806227 ENGINE = InnoDB,
  SUBPARTITION p201806228 ENGINE = InnoDB,
  SUBPARTITION p201806229 ENGINE = InnoDB),
 PARTITION p20180623 VALUES LESS THAN ('2018-06-24')
 (SUBPARTITION p201806230 ENGINE = InnoDB,
  SUBPARTITION p201806231 ENGINE = InnoDB,
  SUBPARTITION p201806232 ENGINE = InnoDB,
  SUBPARTITION p201806233 ENGINE = InnoDB,
  SUBPARTITION p201806234 ENGINE = InnoDB,
  SUBPARTITION p201806235 ENGINE = InnoDB,
  SUBPARTITION p201806236 ENGINE = InnoDB,
  SUBPARTITION p201806237 ENGINE = InnoDB,
  SUBPARTITION p201806238 ENGINE = InnoDB,
  SUBPARTITION p201806239 ENGINE = InnoDB),
 PARTITION p20180624 VALUES LESS THAN ('2018-06-25')
 (SUBPARTITION p201806240 ENGINE = InnoDB,
  SUBPARTITION p201806241 ENGINE = InnoDB,
  SUBPARTITION p201806242 ENGINE = InnoDB,
  SUBPARTITION p201806243 ENGINE = InnoDB,
  SUBPARTITION p201806244 ENGINE = InnoDB,
  SUBPARTITION p201806245 ENGINE = InnoDB,
  SUBPARTITION p201806246 ENGINE = InnoDB,
  SUBPARTITION p201806247 ENGINE = InnoDB,
  SUBPARTITION p201806248 ENGINE = InnoDB,
  SUBPARTITION p201806249 ENGINE = InnoDB),
 PARTITION p20180625 VALUES LESS THAN ('2018-06-26')
 (SUBPARTITION p201806250 ENGINE = InnoDB,
  SUBPARTITION p201806251 ENGINE = InnoDB,
  SUBPARTITION p201806252 ENGINE = InnoDB,
  SUBPARTITION p201806253 ENGINE = InnoDB,
  SUBPARTITION p201806254 ENGINE = InnoDB,
  SUBPARTITION p201806255 ENGINE = InnoDB,
  SUBPARTITION p201806256 ENGINE = InnoDB,
  SUBPARTITION p201806257 ENGINE = InnoDB,
  SUBPARTITION p201806258 ENGINE = InnoDB,
  SUBPARTITION p201806259 ENGINE = InnoDB),
 PARTITION p20180626 VALUES LESS THAN ('2018-06-27')
 (SUBPARTITION p201806260 ENGINE = InnoDB,
  SUBPARTITION p201806261 ENGINE = InnoDB,
  SUBPARTITION p201806262 ENGINE = InnoDB,
  SUBPARTITION p201806263 ENGINE = InnoDB,
  SUBPARTITION p201806264 ENGINE = InnoDB,
  SUBPARTITION p201806265 ENGINE = InnoDB,
  SUBPARTITION p201806266 ENGINE = InnoDB,
  SUBPARTITION p201806267 ENGINE = InnoDB,
  SUBPARTITION p201806268 ENGINE = InnoDB,
  SUBPARTITION p201806269 ENGINE = InnoDB),
 PARTITION p20180627 VALUES LESS THAN ('2018-06-28')
 (SUBPARTITION p201806270 ENGINE = InnoDB,
  SUBPARTITION p201806271 ENGINE = InnoDB,
  SUBPARTITION p201806272 ENGINE = InnoDB,
  SUBPARTITION p201806273 ENGINE = InnoDB,
  SUBPARTITION p201806274 ENGINE = InnoDB,
  SUBPARTITION p201806275 ENGINE = InnoDB,
  SUBPARTITION p201806276 ENGINE = InnoDB,
  SUBPARTITION p201806277 ENGINE = InnoDB,
  SUBPARTITION p201806278 ENGINE = InnoDB,
  SUBPARTITION p201806279 ENGINE = InnoDB)) */
 
--#修改代码
--分区增加
ALTER TABLE test01 ADD PARTITION (
 PARTITION p20180624 VALUES LESS THAN ('2018-06-25')
 (SUBPARTITION p201806240 ENGINE = INNODB,
  SUBPARTITION p201806241 ENGINE = INNODB,
  SUBPARTITION p201806242 ENGINE = INNODB,
  SUBPARTITION p201806243 ENGINE = INNODB,
  SUBPARTITION p201806244 ENGINE = INNODB,
  SUBPARTITION p201806245 ENGINE = INNODB,
  SUBPARTITION p201806246 ENGINE = INNODB,
  SUBPARTITION p201806247 ENGINE = INNODB,
  SUBPARTITION p201806248 ENGINE = INNODB,
  SUBPARTITION p201806249 ENGINE = INNODB));
--分区裁剪
ALTER TABLE test01 DROP PARTITION p20180621;




--#创建存储过程,调用实现分区裁剪;
DELIMITER $$
USE `mrvc`$$
DROP PROCEDURE IF EXISTS `create_Partition2`$$

CREATE DEFINER=`root`@`%` PROCEDURE `create_Partition2`()
BEGIN
/* 事务回滚,其实放这里没什么作用,ALTER TABLE是隐式提交,回滚不了的。*/
DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
START TRANSACTION;
/* 到系统表查出这个表的最大分区,得到最大分区的日期。在创建分区的时候,名称就以日期格式存放,方便后面维护 */
SELECT REPLACE(partition_name,'p','') INTO @date_num FROM INFORMATION_SCHEMA.PARTITIONS
WHERE table_name='test01' ORDER BY partition_ordinal_position DESC LIMIT 1;
SET @Next_date= DATE(DATE_ADD(@date_num+0, INTERVAL 1 DAY))+0;
SET @Max_date= DATE(DATE_ADD(@date_num+0, INTERVAL 2 DAY))+0;
/* 修改表,在最大分区的后面增加一个分区,时间范围加1天 */
SET @s1=CONCAT('ALTER TABLE test01 ADD PARTITION (PARTITION p',@Next_date,' VALUES LESS THAN (''',DATE(@Max_date),''')
 (SUBPARTITION p',@Next_date,'0 ENGINE = INNODB,
  SUBPARTITION p',@Next_date,'1 ENGINE = INNODB,
  SUBPARTITION p',@Next_date,'2 ENGINE = INNODB,
  SUBPARTITION p',@Next_date,'3 ENGINE = INNODB,
  SUBPARTITION p',@Next_date,'4 ENGINE = INNODB,
  SUBPARTITION p',@Next_date,'5 ENGINE = INNODB,
  SUBPARTITION p',@Next_date,'6 ENGINE = INNODB,
  SUBPARTITION p',@Next_date,'7 ENGINE = INNODB,
  SUBPARTITION p',@Next_date,'8 ENGINE = INNODB,
  SUBPARTITION p',@Next_date,'9 ENGINE = INNODB))');
/* 输出查看增加分区语句
SELECT @s1;*/
PREPARE stmt2 FROM @s1;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt2;
 /* 取出最小的分区的名称,并删除掉 。
    注意:删除分区会同时删除分区内的数据,慎重 */
SELECT partition_name INTO @first_num FROM INFORMATION_SCHEMA.PARTITIONS
WHERE table_name='test01' ORDER BY partition_ordinal_position LIMIT 1;
SET @s=CONCAT('ALTER TABLE test01 DROP PARTITION ',@first_num);
/* 输出查看增加分区语句
SELECT @s;*/
PREPARE stmt1 FROM @s;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
COMMIT;
END$$
DELIMITER ;

--#调用方法#
--方法一
--###应用程序调用存储过程
 CALL mrvc.`create_Partition`;  
 
--方法二
--###mysql定时事件执行存储过程
DELIMITER ;
DELIMITER $$
CREATE EVENT Partition_risk_event  
          ON SCHEDULE  
          EVERY 1 day STARTS '2016-05-22 02:00:00'   
          DO  
      BEGIN  

          CALL mrvc.`create_Partition`;  
        
END $$
DELIMITER ;
--eg:  
EXPLAIN
SELECT * FROM test01
WHERE ComputeTime = '2018-06-21 15:32:54'
AND  ItemId = '16136312'


猜你喜欢

转载自blog.csdn.net/demonson/article/details/80772897
今日推荐