ClickHouse/docs/ru/operations/table_engines/summingmergetree.md
BayoNet 0f2ba3043a Significantly change article about SummingMergeTree.
Article is restructured, text is changed in many places of the document. New syntax for table creation is described.
2018-09-19 11:21:53 +03:00

7.8 KiB
Raw Blame History

SummingMergeTree

Движок наследует функциональность MergeTree. Отличие заключается в том, что для таблиц SummingMergeTree при слиянии кусков данных ClickHouse все строки с одинаковым первичным ключом старается заменить на одну, которая хранит только суммы столбцов с цифровым типом данных. Если первичный ключ подобран таким образом, что одному значению ключа соответствует много строк, это значительно уменьшает объем хранения и ускоряет последующую выборку данных.

Мы рекомендуем использовать движок в паре с MergeTree. В MergeTree храните полные данные, а SummingMergeTree используйте для хранения агрегированных данных, например, при подготовке отчетов. Такой подход позволит не утратить ценные данные из-за неправильно выбранного первичного ключа.

Конфигурирование движка при создании таблицы

ENGINE [=] SummingMergeTree([columns]) [PARTITION BY expr] [ORDER BY expr] [SAMPLE BY expr] [SETTINGS name=value, ...]

Параметры SummingMergeTree

  • columns — кортеж с именами столбцов для суммирования данных. Необязательный параметр. Столбцы должны иметь числовой тип и не должны входить в первичный ключ.

Секции ENGINE

SummingMergeTree использует те же секции ENGINE, что и MergeTree.

Устаревший способ конфигурирования движка

!!!attention Не используйте этот способ в новых проектах и по возможности переведите старые проекты на способ описанный выше.

SummingMergeTree(EventDate, (OrderID, EventDate, BannerID, ...), 8192, [columns])

Все параметры, кроме columns имеют то же значение, что в и MergeTree.

  • columns — кортеж с именами столбцов для суммирования данных. Необязательный параметр. Описание смотрите выше по тексту.

Пример использования

Рассмотрим следующую таблицу:

CREATE TABLE summtt
(
    key UInt32,
    value UInt32
)
ENGINE = SummingMergeTree()
ORDER BY key

Добавим в неё данные:

:) INSERT INTO summtt Values(1,1),(1,2),(2,1)

ClickHouse может не просуммировать данные или просуммировать их не полностью (смотрите ниже по тексту), поэтому при запросе мы используем агрегатную функцию sum и секцию GROUP BY.

SELECT key, sum(value) FROM summtt GROUP BY key
┌─key─┬─sum(value)─┐
│   2 │          1 │
│   1 │          3 │
└─────┴────────────┘

Особенности обработки параметров и данных

При вставке данных в таблицу они сохраняются как есть. Периодически ClickHouse выполняет слияние вставленных кусков данных и именно в этот момент производится суммирование и замена многих строк с одинаковым первичным ключом на одну.

ClickHouse рассчитывает расход ресурсов и может не выполнить суммирование или выполнить его не полностью, если посчитает эту операцию слишком затратной. Поэтому, при выборке данных (SELECT) необходимо использовать агрегатную функцию sum() и секцию GROUP BY как описано в примере выше.

Суммирование простых данных

Если столбцы для суммирования не заданы, то ClickHouse суммирует значения в столбцах с числовым типом данных, не входящих в первичный ключ.

Если столбцы для суммирования заданы, то для всех строчек с одинаковым значением первичного ключа ClickHouse суммирует значения в указанных столбцах. Столбцы должны обязательно иметь числовой тип данных.

Если значения во всех столбцах для суммирования оказались нулевыми, то строчка удаляется.

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

Столбцы, входящие в первичный ключ не суммируются.

Суммирование в столбцах AggregateFunction

Для столбцов типа AggregateFunction ClickHouse выполняет агрегацию согласно заданной функции, повторяя поведение движка AggregatingMergeTree.

Обработка вложенных структур

Таблица может иметь вложенные структуры данных, которые обрабатываются особым образом.

Если название вложенной таблицы заканчивается на Map и она содержит не менее двух столбцов, удовлетворяющих критериям:

  • первый столбец - числовой (*Int*, Date, DateTime), назовем его условно key,
  • остальные столбцы - арифметические (*Int*, Float32/64), условно (values...),

то вложенная таблица воспринимается как отображение key => (values...) и при слиянии её строк выполняется слияние элементов двух множеств по key со сложением соответствующих (values...).

Примеры:

[(1, 100)] + [(2, 150)] -> [(1, 100), (2, 150)]
[(1, 100)] + [(1, 150)] -> [(1, 250)]
[(1, 100)] + [(1, 150), (2, 150)] -> [(1, 250), (2, 150)]
[(1, 100), (2, 150)] + [(1, -100)] -> [(2, 150)]

При запросе данных используйте функцию sumMap(key, value) для агрегации Map.

Для вложенной структуры данных не нужно указывать её столбцы в кортеже столбцов для суммирования.