Обновление проблем со скоростью при оставлении соединения в поле даты - PullRequest
0 голосов
/ 07 июня 2018

У меня есть таблица, в которой хранятся точки данных временных рядов в MySQL 5.6, которые называются data_points

CREATE TABLE `data_points` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `time_series_id` int(10) unsigned NOT NULL,
  `logged_at` date NOT NULL,
  `data_value` decimal(20,6) DEFAULT NULL,
  `upload_id` int(10) unsigned NOT NULL,
  `is_latest` tinyint(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`id`),
  KEY `data_points_time_series_id_index` (`time_series_id`),
  KEY `data_points_logged_at_index` (`logged_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

. Флаг is_latest указывает, является ли точка данных самой последней для данной даты logged_at иучитывая time_series_id.Когда новые точки данных вставляются, мне нужно сохранить старые ревизии, но установить их флаг is_latest на 0.

Например, на 2018-01-01 Я вставляю первую точку данных со значением 1457.2для time_series_id 123.Значением по умолчанию is_latest является 1.

Позже я хочу пересмотреть это значение точки данных (при этом оставляя существующую строку на месте по соображениям анализа момента времени).Поэтому я вставляю новую точку данных для 2018-01-01 со значением 44795.778 для time_series_id 123.

Теперь мне нужно установить флаг is_latest на 0 для старой ревизии.

У меня есть запрос на обновление, чтобы выполнить это, но для выполнения требуется ~ 400 мс с ~ 3 миллионами строк в таблице data_points ...

UPDATE data_points o
LEFT JOIN data_points o2
  ON o2.time_series_id = o.time_series_id
  AND o2.logged_at = o.logged_at
SET o.is_latest = 0
WHERE o.is_latest = 1
  AND o.time_series_id = 123
  AND o.upload_id < o2.upload_id;

Я думаю, что проблема в том,на самосоединение в o2.logged_at = o.logged_at, при объединении в даты.

Есть ли более эффективный способ определить, какую из data_points строк следует пометить как is_latest = 0?

Ответы [ 2 ]

0 голосов
/ 08 июня 2018
INDEX(time_series_id, is_latest, o.upload_id)

Но мне интересно.Зачем иметь флаг is_latest, когда «самый большой upload_id» имеет то же значение?Давайте посмотрим на запрос, который использует is_latest, и посмотрим, сможем ли мы избавиться от флага.Это сделало бы запрос на 100% быстрее, избавившись от него!

0 голосов
/ 07 июня 2018

Для этого запроса:

UPDATE data_points o LEFT JOIN
       data_points o2
       ON o2.time_series_id = o.time_series_id AND
          o2.logged_at = o.logged_at
    SET o.is_latest = 0
WHERE o.is_latest = 1 AND
      o.time_series_id = 123 AND
      o.upload_id < o2.upload_id;

Вам нужны два индекса: data_points(is_latest, time_series_id) и data_points(time_series_id, logged_at, upload_id).Первый может уже охватываться вашими существующими индексами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...