Перейти к основному содержанию
Короткий ответ — “нет”. Рабочая нагрузка ключ-значение — один из тех сценариев, где НЕ стоит использовать ClickHouse. Всё-таки это OLAP-система, а для задач ключ-значение существует множество отличных решений. Однако бывают ситуации, когда использовать ClickHouse для запросов в стиле ключ-значение всё же имеет смысл. Обычно речь идёт о недорогих продуктах, где основная рабочая нагрузка носит аналитический характер и хорошо подходит для ClickHouse, но при этом есть и какой-то второстепенный процесс, которому нужен паттерн ключ-значение — с не слишком высокой пропускной способностью запросов и без жёстких требований к задержке. Если бы у вас был неограниченный бюджет, вы бы развернули отдельную базу данных ключ-значение для этой второстепенной рабочей нагрузки, но в реальности сопровождение ещё одной системы хранения требует дополнительных затрат (мониторинг, резервные копии и т. д.), которых часто хочется избежать. Если вы всё же решите пойти против рекомендаций и выполнять в ClickHouse запросы в стиле ключ-значение, вот несколько советов:
  • Основная причина, по которой точечные запросы в ClickHouse обходятся дорого, — его разреженный первичный индекс в основном семействе движков таблиц MergeTree. Этот индекс не может указывать на каждую конкретную строку данных: вместо этого он указывает на каждую N-ю строку, и системе приходится сканировать данные от соседней N-й строки до нужной, попутно считывая лишнее. В сценарии ключ-значение может быть полезно уменьшить значение N с помощью настройки index_granularity.
  • ClickHouse хранит каждый столбец в отдельном наборе файлов, поэтому, чтобы собрать одну полную строку, ему нужно пройти по каждому из них. Их количество линейно растёт вместе с числом столбцов, поэтому в сценарии ключ-значение может быть разумно избегать большого количества столбцов и помещать всю полезную нагрузку в один столбец String, закодированный в каком-либо формате сериализации — например, JSON, Protobuf или любом другом подходящем.
  • Есть и альтернативный подход: вместо обычных таблиц MergeTree использовать движок таблицы Join, а для получения данных — функцию joinGet. Он может дать более высокую производительность запросов, но при этом возможны проблемы с удобством использования и надёжностью. Вот пример использования.
Последнее изменение 10 июня 2026 г.