我正在尝试将我的表分区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范围。我该怎么办?
提前致谢!
答案 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驱动程序(等)。
如果X
和Y
是经度和纬度,则更容易这样命名。根据您拥有(和需要)的分辨率,使用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
涵盖了如何从这种蠢事中恢复过来。