summingmergetree.md 8.7 KB
Newer Older
1
# SummingMergeTree {#summingmergetree}
2

A
Alexey Milovidov 已提交
3
Движок наследует функциональность [MergeTree](mergetree.md#table_engines-mergetree). Отличие заключается в том, что для таблиц `SummingMergeTree` при слиянии кусков данных ClickHouse все строки с одинаковым первичным ключом (точнее, с одинаковым [ключом сортировки](mergetree.md)) заменяет на одну, которая хранит только суммы значений из столбцов с цифровым типом данных. Если ключ сортировки подобран таким образом, что одному значению ключа соответствует много строк, это значительно уменьшает объём хранения и ускоряет последующую выборку данных.
4 5 6

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

7
## Создание таблицы {#sozdanie-tablitsy}
8

9
``` sql
10 11 12 13 14
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
    name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
    ...
15
) ENGINE = SummingMergeTree([columns])
16 17 18 19 20 21
[PARTITION BY expr]
[ORDER BY expr]
[SAMPLE BY expr]
[SETTINGS name=value, ...]
```

22
Описание параметров запроса смотрите в [описании запроса](../../../engines/table-engines/mergetree-family/summingmergetree.md).
23 24 25

**Параметры SummingMergeTree**

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

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

**Секции запроса**

S
Sergei Bocharov 已提交
33
При создании таблицы `SummingMergeTree` используются те же [секции](mergetree.md) запроса, что и при создании таблицы `MergeTree`.
34

35 36 37
<details markdown="1">

<summary>Устаревший способ создания таблицы</summary>
38

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

42
``` sql
43 44 45 46 47 48
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
    name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
    ...
) ENGINE [=] SummingMergeTree(date-column [, sampling_expression], (primary, key), index_granularity, [columns])
49
```
50

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

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

55 56
</details>

57
## Пример использования {#primer-ispolzovaniia}
58 59

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

61
``` sql
62 63 64 65 66 67 68
CREATE TABLE summtt
(
    key UInt32,
    value UInt32
)
ENGINE = SummingMergeTree()
ORDER BY key
69
```
70

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

73
``` sql
74
INSERT INTO summtt Values(1,1),(1,2),(2,1)
75
```
76

I
Ivan Blinkov 已提交
77
ClickHouse может не полностью просуммировать все строки ([смотрите ниже по тексту](#obrabotka-dannykh)), поэтому при запросе мы используем агрегатную функцию `sum` и секцию `GROUP BY`.
78

79
``` sql
80 81
SELECT key, sum(value) FROM summtt GROUP BY key
```
82 83

``` text
84 85 86 87 88 89
┌─key─┬─sum(value)─┐
│   2 │          1 │
│   1 │          3 │
└─────┴────────────┘
```

90
## Обработка данных {#obrabotka-dannykh}
91 92 93

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

94
ClickHouse может слить куски данных таким образом, что не все строки с одинаковым первичным ключом окажутся в одном финальном куске, т.е. суммирование будет не полным. Поэтому, при выборке данных (`SELECT`) необходимо использовать агрегатную функцию [sum()](../../../engines/table-engines/mergetree-family/summingmergetree.md#agg_function-sum) и секцию `GROUP BY` как описано в примере выше.
95

96
### Общие правила суммирования {#obshchie-pravila-summirovaniia}
97 98 99 100

Суммируются значения в столбцах с числовым типом данных. Набор столбцов определяется параметром `columns`.

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

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

104
Значения для столбцов, входящих в первичный ключ, не суммируются.
K
KochetovNicolai 已提交
105

106
### Суммирование в столбцах AggregateFunction {#summirovanie-v-stolbtsakh-aggregatefunction}
107

108
Для столбцов типа [AggregateFunction](../../../sql-reference/data-types/aggregatefunction.md#data-type-aggregatefunction) ClickHouse выполняет агрегацию согласно заданной функции, повторяя поведение движка [AggregatingMergeTree](aggregatingmergetree.md).
109

110
### Вложенные структуры {#vlozhennye-struktury}
111 112 113 114 115

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

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

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

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

Примеры:
122

123
``` text
124 125 126 127 128
[(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)]
```
129

130
При запросе данных используйте функцию [sumMap(key, value)](../../../engines/table-engines/mergetree-family/summingmergetree.md) для агрегации `Map`.
131

132
Для вложенной структуры данных не нужно указывать её столбцы в кортеже столбцов для суммирования.
I
Ivan Blinkov 已提交
133

I
Ivan Blinkov 已提交
134
[Оригинальная статья](https://clickhouse.tech/docs/ru/operations/table_engines/summingmergetree/) <!--hide-->