У меня есть данные временных рядов о количестве предметов, которые я храню (в этом примере с игрушкой) в простой паре таблиц.На данный момент это делается в MySQL, но если существуют достаточно веские причины для решения моей проблемы в другой СУБД, я был бы всем вниманием!
Таблица ITEM
имеет первичный ключ иодин текстоподобный столбец, который можно представить как описание, назовем его descr
.Таблица DATAPOINT
имеет первичный ключ и 3 других столбца: внешний ключ в таблицу ITEM
(назовите его fk_item
), дату и время, которое я назову timestamp
, и значение с плавающей запятой, которое мы назовем value
.Кроме того, существует совместное ограничение уникальности для пары столбцов (fk_item, timestamp)
(нам нужно только одно значение в БД для данного элемента в данный момент времени).
Чтобы поставить на него действительные числа, DATAPOINT
таблица содержит около 1 миллиарда строк, что является результатом наличия приблизительно 100 тысяч строк для каждого из 10 тысяч различных элементов.
Мой вопрос касается возможности оптимизировать производительность как чтения, так и записи в этом контексте, и наилучшим способомчтобы обеспечить соблюдение этого ограничения уникальности.
Типичное чтение из этой БД будет включать небольшое количество элементов (полдюжины?), для которых мы хотим получить все значения в заданном диапазоне времени / даты (содержащие примерно 1 тыс. точек навещь).Для этого было бы очень удобно иметь индекс, равный (fk_item, timestamp)
, и применять совместные критерии уникальности для этого индекса.Эта мотивация для чтения такого типа: «Я хочу сделать линейный график из 2 или 3 элементов для этого 3-летнего диапазона».
Однако типичная запись для этой базы данных будет выглядеть совсем иначе.Это будет вставка одной точки данных для каждого из нескольких тысяч элементов с одинаковыми (или небольшим числом) временными метками.Эта мотивация для такой записи может быть интуитивно понятна как: «Я хочу добавить вчерашнюю точку данных для каждого отдельного элемента».Поэтому для записей такого рода было бы более практично иметь индекс, равный (timestamp, fk_item)
, и применять ограничение уникальности для этого индекса.
Важно, что для масштаба моих данных и оборудования нииз этих индексов могут быть полностью помещены в ОЗУ.
Как правило, подавляющее большинство операций записи происходит в течение короткого времени каждый день: т.е. в конце каждого дня все данные за этот день записываются в виде15-минутный период, а затем чтение происходит в течение дня (но обычно не в течение этого 15-минутного периода).
Итак, насколько я понимаю, если я строю таблицу с индексом (fk_item, timestamp)
, оптимизированным для чтения (и поместите ограничение уникальности там), тогда мои типичные чтения будут хорошими и быстрыми.Но я обеспокоен тем, что мои записи будут медленными, потому что нам нужно будет обновить индекс несмежным способом.Однако, если я построю таблицу с индексом (timestamp, fk_item)
, оптимизированным для записи (и наложу ограничение уникальности), то мои типичные операции записи будут быстрыми, но мои типичные операции чтения пострадают.
Есть ли способ получить лучшее из обоих миров?Например, если я построю два индекса: (fk_item, timestamp)
и (timestamp, fk_item)
и добавлю уникальность only к последнему из двух, будет ли это работать хорошо?Или же запись все равно будет продолжаться с «медленной» скоростью, потому что даже при наличии индекса, оптимизированного для записи (например, для проверки ограничения уникальности), индекс, оптимизированный для чтения, необходимо будет обновить при любых вставках, и это обновление будетбыть несмежным?
Заранее спасибо!