按列时间戳分区mysql表

时间:2018-05-09 09:48:19

标签: mysql partition database-partitioning

我正在尝试将我的表分区MySQL innoDB。现在,位置表(并且总是增长)的历史数据行中大约有200万行。我必须逐年删除旧数据集 我使用MySQL 5.7.22社区服务器。

CREATE TABLE `geo_data` (
  `ID` bigint(20) NOT NULL AUTO_INCREMENT,
  `ID_DISP` bigint(20) DEFAULT NULL,
  `SYS_TIMESTAMP` datetime DEFAULT NULL,
  `DATA_TIMESTAMP` bigint(20) DEFAULT NULL,
  `X` double DEFAULT NULL,
  `Y` double DEFAULT NULL,
  `SPEED` bigint(20) DEFAULT NULL,
  `HEADING` bigint(20) DEFAULT NULL,
  `ID_DATA_TYPE` bigint(20) DEFAULT NULL,
  `PROCESSED` bigint(20) DEFAULT NULL,
  `ALTITUDE` bigint(20) DEFAULT NULL,
  `ID_UNIT` bigint(20) DEFAULT NULL,
  `ID_DRIVER` bigint(20) DEFAULT NULL,
  UNIQUE KEY `part_id` (`ID`,`DATA_TIMESTAMP`,`ID_DISP`),
  KEY `Index_idDisp_dataTS_type` (`ID_DISP`,`DATA_TIMESTAMP`,`ID_DATA_TYPE`),
  KEY `Index_idDisp_dataTS` (`ID_DISP`,`DATA_TIMESTAMP`),
  KEY `Index_TS` (`DATA_TIMESTAMP`),
  KEY `idx_sysTS_idDisp` (`ID_DISP`,`SYS_TIMESTAMP`),
  KEY `idx_clab_geo_data_ID_UNIT_DATA_TIMESTAMP_ID_DATA_TYPE` (`ID_UNIT`,`DATA_TIMESTAMP`,`ID_DATA_TYPE`),
  KEY `idx_idUnit_dataTS` (`ID_UNIT`,`DATA_TIMESTAMP`),
  KEY `idx_clab_geo_data_ID_DRIVER_DATA_TIMESTAMP_ID_DATA_TYPE` (`ID_DRIVER`,`DATA_TIMESTAMP`,`ID_DATA_TYPE`)
) ENGINE=InnoDB AUTO_INCREMENT=584390 DEFAULT CHARSET=latin1;

我必须按DATA_TIMESTAMP进行分区(格式时间戳日期gps)。

ALTER TABLE geo_data
PARTITION BY RANGE (year(from_unixtime(data_timestamp)))
(
   PARTITION p2018 VALUES LESS THAN ('2018'),
   PARTITION p2019 VALUES LESS THAN ('2019'),
   PARTITION pmax VALUES LESS THAN MAXVALUE
);
  

错误代码:1697。分区'p2018'的VALUES值必须为INT

我该怎么办?

我想稍后通过ID_DISP添加一个subpartion范围。我该怎么办?

提前致谢!

2 个答案:

答案 0 :(得分:0)

<强>更新

似乎您无法在from_unixtime查询中使用PARTITION BY RANGE,因为散列分区必须基于整数表达式。更多信息see this answer

它期待INT不是STRING(根据错误消息),所以请尝试:

ALTER TABLE geo_data
PARTITION BY RANGE (year(from_unixtime(data_timestamp)))
(
   PARTITION p2018 VALUES LESS THAN (2018),
   PARTITION p2019 VALUES LESS THAN (2019),
   PARTITION pmax VALUES LESS THAN MAXVALUE
);

这里我将分区值中的年份指定为int,即2018/2019,而不是'2018'/'2019'中的字符串

答案 1 :(得分:0)

由于data_timestamp实际上是BIGINT,因此不允许您使用日期函数。看来有两个错误,这可能可以解决它们:

ALTER TABLE geo_data
PARTITION BY RANGE (data_timestamp)
(
   PARTITION p2018 VALUES LESS THAN (UNIX_TIMESTAMP('2018-01-01') * 1000),
   PARTITION p2019 VALUES LESS THAN (UNIX_TIMESTAMP('2019-01-01') * 1000),
   PARTITION pmax VALUES LESS THAN MAXVALUE
);

我假设您的data_timestamp确实是毫秒,是Java吗?如果没有,请决定如何处理* 1000

SUBPARTITIONs没有用;不要打扰他们。如果您确实要按月或按季度进行分区,则只需在PARTITION级别进行即可。

建议:分区不超过50个。

您有多少个“驾驶员”?我怀疑你没有万亿美元。因此,请勿盲目使用BIGINT作为ID。每个占用8个字节。例如,SMALLINT UNSIGNED仅占用2个字节,并允许64K驱动程序(等)。

如果XY是经度和纬度,则更容易这样命名。根据您拥有(和需要)的分辨率,使用Here而不是8字节DOUBLE的数据类型。 4字节的FLOATs足够用于车辆。

该表具有多个冗余索引;折腾他们。另外,请注意,当您拥有INDEX(a,b,c)时,也拥有INDEX(a,b)是多余的。

另请参阅我关于分区的discussion,尤其是与时间序列(例如您的时间序列)有关的

嗯...我想知道SPEED的63位精度是否会让您以光速记录它们?

另一个要点:直到2019年初之前都不要创建p2019。如果有pmax,以防您无法及时添加该分区,请创建REORGANIZE PARTITION。我的讨论中提到的parameter_list : parameter | parameter_list COMMA parameter parameter : ID COL WHITESPACE TYPE 涵盖了如何从这种蠢事中恢复过来。