Перейти к основному содержимому
Перейти к основному содержимому

Движок таблиц памяти

примечание

При использовании движка таблиц памяти в ClickHouse Cloud данные не реплицируются по всем узлам (по замыслу). Чтобы гарантировать, что все запросы направляются на один и тот же узел и что движок таблиц памяти работает как ожидается, вы можете сделать одно из следующего:

  • Выполнить все операции в одной сессии
  • Использовать клиент, который использует TCP или нативный интерфейс (что позволяет поддерживать надежные соединения), такой как clickhouse-client

Движок памяти хранит данные в ОЗУ в несжатом виде. Данные хранятся в точно том же виде, в каком они были получены при чтении. Другими словами, чтение из этой таблицы полностью бесплатно.
Совместный доступ к данным синхронизирован. Блокировки короткие: операции чтения и записи не блокируют друг друга.
Индексы не поддерживаются. Чтение параллелизовано.

Максимальная продуктивность (более 10 ГБ/с) достигается на простых запросах, поскольку нет чтения с диска, распаковки или десериализации данных. (Следует отметить, что в многих случаях продуктивность движка MergeTree почти так же высока.)
При перезапуске сервера данные исчезают из таблицы, и таблица становится пустой.
Как правило, использование этого движка таблиц не оправдано. Однако его можно использовать для тестов и для задач, где требуется максимальная скорость на относительно небольшом количестве строк (до примерно 100,000,000).

Движок памяти используется системой для временных таблиц с внешними данными запросов (см. раздел "Внешние данные для обработки запроса") и для реализации GLOBAL IN (см. раздел "IN операторы").

Можно задать верхние и нижние пределы для ограничения размера таблицы движка памяти, что позволяет фактически использовать ее как кольцевой буфер (см. Параметры движка).

Параметры движка

  • min_bytes_to_keep — Минимальное количество байт для хранения, когда таблица памяти ограничена по размеру.
    • Значение по умолчанию: 0
    • Требуется max_bytes_to_keep
  • max_bytes_to_keep — Максимальное количество байт для хранения в таблице памяти, где старые строки удаляются при каждом добавлении (т.е. кольцевой буфер). Максимальное количество байт может превышать указанный предел, если самая старая партия строк для удаления попадает под предел min_bytes_to_keep при добавлении большого блока.
    • Значение по умолчанию: 0
  • min_rows_to_keep — Минимальное количество строк для хранения, когда таблица памяти ограничена по размеру.
    • Значение по умолчанию: 0
    • Требуется max_rows_to_keep
  • max_rows_to_keep — Максимальное количество строк для хранения в таблице памяти, где старые строки удаляются при каждом добавлении (т.е. кольцевой буфер). Максимальное количество строк может превышать указанный предел, если самая старая партия строк для удаления попадает под предел min_rows_to_keep при добавлении большого блока.
    • Значение по умолчанию: 0
  • compress - Нужно ли сжимать данные в памяти.
    • Значение по умолчанию: false

Использование

Инициализация настроек

CREATE TABLE memory (i UInt32) ENGINE = Memory SETTINGS min_rows_to_keep = 100, max_rows_to_keep = 1000;

Изменение настроек

ALTER TABLE memory MODIFY SETTING min_rows_to_keep = 100, max_rows_to_keep = 1000;

Примечание: Параметры ограничения bytes и rows могут быть заданы одновременно, однако будут соблюдены нижние пределы max и min.

Примеры

CREATE TABLE memory (i UInt32) ENGINE = Memory SETTINGS min_bytes_to_keep = 4096, max_bytes_to_keep = 16384;

/* 1. тестирование, что самая старая партия не удаляется из-за нижнего предела - 3000 строк */
INSERT INTO memory SELECT * FROM numbers(0, 1600); -- 8'192 байт

/* 2. добавление блока, который не удаляется */
INSERT INTO memory SELECT * FROM numbers(1000, 100); -- 1'024 байта

/* 3. тестирование, что самая старая партия удаляется - 9216 байт - 1100 */
INSERT INTO memory SELECT * FROM numbers(9000, 1000); -- 8'192 байт

/* 4. проверка, что очень большой блок перекрывает все */
INSERT INTO memory SELECT * FROM numbers(9000, 10000); -- 65'536 байт

SELECT total_bytes, total_rows FROM system.tables WHERE name = 'memory' and database = currentDatabase();
┌─total_bytes─┬─total_rows─┐
│       65536 │      10000 │
└─────────────┴────────────┘

также, для строк:

CREATE TABLE memory (i UInt32) ENGINE = Memory SETTINGS min_rows_to_keep = 4000, max_rows_to_keep = 10000;

/* 1. тестирование, что самая старая партия не удаляется из-за нижнего предела - 3000 строк */
INSERT INTO memory SELECT * FROM numbers(0, 1600); -- 1'600 строк

/* 2. добавление блока, который не удаляется */
INSERT INTO memory SELECT * FROM numbers(1000, 100); -- 100 строк

/* 3. тестирование, что самая старая партия удаляется - 9216 байт - 1100 */
INSERT INTO memory SELECT * FROM numbers(9000, 1000); -- 1'000 строк

/* 4. проверка, что очень большой блок перекрывает все */
INSERT INTO memory SELECT * FROM numbers(9000, 10000); -- 10'000 строк

SELECT total_bytes, total_rows FROM system.tables WHERE name = 'memory' and database = currentDatabase();
┌─total_bytes─┬─total_rows─┐
│       65536 │      10000 │
└─────────────┴────────────┘