Partiton MySQL таблицы по метке времени столбца - PullRequest
0 голосов
/ 09 мая 2018

Я пытаюсь разбить мою таблицу MySQL на innoDB.На данный момент в таблице местоположений (и постоянно растущих) строк истории хранится около 2 миллионов строк.Я должен периодически удалять старый набор данных по году, когда я использую 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. Значение VALUES для раздела 'p2018' должно иметь тип INT

Как это сделать?

Я хотел бы добавить позже диапазон подэлементов наID_DISP.Как мне это сделать?

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 11 июля 2018

Поскольку 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 для идентификаторов. Каждый занимает 8 байтов. Например, SMALLINT UNSIGNED будет занимать всего 2 байта и разрешать драйверы 64 КБ (и т. Д.).

Если X и Y - широта и долгота, возможно, было бы понятнее назвать их таковыми. Здесь - какой тип данных использовать вместо 8-байтового DOUBLE, в зависимости от разрешения, которое у вас есть (и нужно). 4 байта FLOATs, вероятно, достаточно хороши для транспортных средств.

Таблица имеет несколько избыточных индексов; бросить их. Кроме того, обратите внимание, что если у вас INDEX(a,b,c), избыточно иметь также INDEX(a,b).

См. Также мое обсуждение по разделению, особенно относящемуся к временным рядам, таким как ваш.

Хммм ... Интересно, 63 бита точности для SPEED позволят вам записывать их, когда они идут со скоростью света?

Еще один момент: не создавайте p2019 до начала 2019 года. У вас есть pmax на тот случай, если вы лукавите и не можете вовремя добавить этот раздел. И REORGANIZE PARTITION, упомянутый в моем обсуждении, описывает, как оправиться от такой глупости.

0 голосов
/ 09 мая 2018

Обновление:

Кажется, вы не можете использовать from_unixtime в запросе PARTITION BY RANGE, потому что хеш-разделы должны основываться на целочисленном выражении. Подробнее см. Этот ответ

Ожидается 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'

...