Как стать автором
Обновить

Комментарии 5

Грамотно построенный запрос - хорошо. Грамотно построенная архитектура - залог успеха!

Ну можно, конечно, скриптами обсчитывать. А можно было бы использовать Materialized View и писать в SummingMergeTree

В целом Вы правы, можно, и решений можно найти несколько, но конкретно под нашу задачу нам показалось проще сделать скриптами, потому что:

  1. Исходная таблица, если вкратце, — это готовая к использованию витрина, которая хранит результат нескольких трансформаций, она не просто пополняется новыми строками, а перестраивается целыми партициями через DROP/REPLACE, а мы, решая свою задачу, за наполнение исходной таблицы можем и не отвечать. Т.к. mat.view забирает новые строки из результата SELECT и вставляет в целевую таблицу, оно бы дублировало данные в целевой SummingMergeTree таблице. Можно было бы сделать другую более подходящую исходную таблицу для mat.view->SummingMergeTree, например, в которую пишется только инкремент изменений. Но для наполнения этой таблицы инкрементов скорее всего также понадобился бы скрипт или непростая цепочка mat.view->table и доп. место в БД.

  2. SummingMergeTree (как и другие подобные "схлопывающие строки" движки таблиц CH) объединяет строки в неопределённый момент времени. А хотелось бы иметь готовую к использованию витрину и в любой момент быть уверенным, что там нет дублей. Из SummingMergeTree-таблицы пришлось бы выбирать данные не простым запросом SELECT/WHERE, а дополнительно еще раз агрегировать, не хотелось нагружать этой агрегацией клиентские приложения, которые забирают данные из витрины, или удлинять цепочку преобразований еще одним mat.view.

а почему именно 50? почему не 24 что логичнее?или 96(15-минутные интервалы)?

просто "выборки" потом строить по Этим партициям по 28,8 минут(1728сек) несколько неудобно будет когда можно было сразу бы оперировать именно партициями....

Добрый день!

Спасибо за вопрос, в данном случае мы партиционировали по дате + остаток от кода продукта:
PARTITION BY toUInt64(concat(toString(toYYYYMMDD(date)), toString(productCode % 50)))

модуль (деления с остатком) в данном случае никак не влияет на временной ряд - у нас как хранились данные за целые сутки в одной партиции, так и хранятся, от модуля остатка зависит строки с какими кодами продуктов в какую партицию попадут (в одной дате).

50 было получено эмпирическим путём, мы пробовали 5, 10, 25, 50 и даже 100. Чем больше модуль (деления с остатком), тем меньше оперативной памяти требуется для однопоточного перестроения витрины с даты T-N, но начиная с какого-то момента (в нашем случае оказалось при модуле > ~50) эффективность этой пропорции падает, поэтому важно найти золотую середину, как написали в конце статьи.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий