ClickHouse для начинающих: зачем нужен и чем отличается от PostgreSQL

Как устроено колоночное хранение

ClickHouse для начинающих: зачем нужен и чем отличается от PostgreSQL

Аналитик просит посчитать метрику за год по всем заказам. Запрос уходит в PostgreSQL, база пыхтит минут десять, а потом падает. Это классическая ситуация, когда инструмент используют не по назначению. СУБД PostgreSQL отлично справляется с тем, чтобы быстро записать новый заказ или обновить статус оплаты. Но когда нужно перелопатить миллионы строк в базе данных ради одной цифры, он сдаёт позиции. Для таких задач придумали ClickHouse. В статье подробно расскажем о том, как он устроен, откуда берёт скорость и в каких проектах будет лишним.

ВАМ ПРИШЛО ПРИГЛАШЕНИЕ 💌
Приходите к нам в соцсети поделиться своим мнением и почитать, что пишут другие. А ещё там выходит дополнительный контент, которого нет на сайте — шпаргалки, опросы и разная дурка. В общем, вот тележка, вот ВК — велком!

Что такое ClickHouse и откуда он взялся

ClickHouse — это колоночная СУБД с открытым исходным кодом, которую создали для аналитических запросов на больших объёмах данных. Проще говоря, она заточена под то, чтобы быстро считать агрегаты по миллиардам строк.

История началась в Яндексе. Команде Яндекс Метрики нужно было строить отчёты по огромному потоку событий — просмотрам, кликам, конверсиям. Данных становилось всё больше, а стандартные базы не тянули. В 2009 году появился первый прототип, в 2012-м ClickHouse уже работал в продакшене, а в 2016 году Яндекс выложил исходники на GitHub под лицензией Apache 2.0. Сейчас развитием занимается компания ClickHouse Inc., а сама база живёт своей жизнью в тысячах проектов по всему миру.

В России у ClickHouse тоже есть официальный контур. Компания Arenadata выпускает дистрибутив Arenadata QuickMarts на базе ClickHouse, который включён в реестр отечественного ПО. А в Yandex Cloud есть управляемый сервис для тех, кто не хочет администрировать кластер вручную.

Версии ClickHouse нумеруются по схеме год.месяц. Релизы выходят каждый месяц, раз в полгода — LTS-версия с длительной поддержкой. На момент написания статьи актуальная стабильная версия — 26.7.3.19, а текущий LTS — 26.3, который поддерживается до марта 2027 года.

Как устроено колоночное хранение

Чтобы понять, почему ClickHouse так быстро считает аналитику, стоит разобраться, как он хранит данные на диске.

Возьмем таблицу заказов: 50 колонок и 100 млн строк. Нужно посчитать сумму по одной колонке — например, общую выручку. В реляционных базах данные лежат построчно: PostgreSQL читает строку целиком, даже если нужна одна колонка — база вытащит с диска всю строку со всеми пятьюдесятью полями.

ClickHouse хранит каждую колонку отдельно. Он читает один файл с нужной колонкой и не трогает остальные 49. Разница в объёме прочитанных данных — 50-кратная. Именно поэтому агрегатные запросы в ClickHouse выполняются за секунды там, где PostgreSQL будет думать минутами.

Строки и колонки на одном примере

Как выглядят данные на диске для обоих вариантов.

Построчное хранение (PostgreSQL):

[заказ_1, товар_А, 1000, оплачен, 2026-01-15]
[заказ_2, товар_Б, 2500, ожидает, 2026-01-15]
[заказ_3, товар_А, 800,  оплачен, 2026-01-16]

Поколоночное хранение (ClickHouse):

заказ_id:  [1, 2, 3]
товар:     [А, Б, А]
сумма:     [1000, 2500, 800]
статус:    [оплачен, ожидает, оплачен]
дата:      [2026-01-15, 2026-01-15, 2026-01-16]

Схема раскладки данных на диске: при построчном хранении все поля строки лежат рядом, при  колоночном — каждая колонка хранится отдельным файлом.

Запрос SELECT SUM(сумма) FROM orders в PostgreSQL прочитает все пять колонок для каждой строки. ClickHouse прочитает только файл с колонкой «сумма» — в пять раз меньше данных.

Почему колонки сжимаются в разы лучше

В одной колонке лежат однотипные данные. Даты рядом с датами, статусы рядом со статусами, числа рядом с числами. Это создаёт идеальные условия для сжатия.

ClickHouse применяет двухступенчатую схему: сначала кодирование с учётом типа данных, потом общие кодеки вроде LZ4 или ZSTD. Для дат работает Delta-кодирование — вместо самих дат хранятся разницы между соседними значениями. Для строк с небольшим количеством уникальных значений — словарное кодирование, когда вместо повторяющихся строк хранятся короткие индексы. Для чисел с плавающей точкой — Gorilla-кодирование, которое отбрасывает незначащие биты.

Практический результат: на бенчмарке ClickBench с датасетом в 100 млн строк ClickHouse сжимает данные до 9,26 ГиБ, тогда как PostgreSQL занимает около 100 ГиБ. Разница в десять раз — прямое следствие архитектуры хранения.

OLTP и OLAP — две разные задачи для базы

В мире баз данных есть два больших класса нагрузок, и их часто путают.

OLTP (Online Transaction Processing) обслуживает поток коротких операций. Оформить заказ, списать деньги, обновить профиль пользователя. Каждый запрос затрагивает одну-две строки, но таких запросов — тысячи в секунду. Здесь важна скорость записи и целостность данных. Это работа для PostgreSQL.

OLAP (Online Analytical Processing) работает по иному принципу. Запросов мало, но каждый перелопачивает миллионы строк ради агрегата. Выручка по регионам за квартал, воронка по группам пользователей, средний чек по месяцам. Здесь важна скорость чтения и агрегации. Это работа для ClickHouse.

Базы не конкурируют по назначению. Они закрывают разные типы нагрузок, поэтому попытка заставить одну делать работу другой обычно заканчивается плохо.

Чем ClickHouse отличается от PostgreSQL

Таблица сравнения PostgreSQL и ClickHouse: ClickHouse vs PostgreSQL по ключевым параметрам.

ПараметрPostgreSQLClickHouse
Хранениепострочноепоколоночное
Тип нагрузкиOLTPOLAP
Транзакцииполноценный ACID, MVCCограниченно, атомарность на уровне вставки блока
Первичный ключуникальный, B-treeразреженный, не требует уникальности
Вставкапо одной строке нормальнопакетами, мелкие вставки вредны
JOINсильная сторона, планировщик перестраивает запросыработает, но требует ручной оптимизации
Масштабированиевертикальное, реплики для чтениявертикальное и горизонтальное, шардирование из коробки
Изменение данныхUPDATE и DELETE штатноlightweight UPDATE и DELETE через patch-части

Каждая строка этой таблицы описывает компромисс, который база делает ради своей специализации. PostgreSQL силён в транзакциях и целостности, но проигрывает в скорости сканирования больших таблиц. ClickHouse читает миллиарды строк за секунды, но не умеет в полноценные транзакции. При выборе инструмента всё решает профиль запросов: что происходит чаще — запись одной строки или агрегация миллионов. 

Как в ClickHouse устроены таблицы, ключи и индексы

Основа ClickHouse — движок таблиц MergeTree. 

Так выглядит создание таблицы для хранения событий:

-- Создаём таблицу с движком MergeTree
CREATE TABLE events (
    -- идентификатор пользователя
    user_id UInt64,
    -- время события
    event_time DateTime,
    -- тип события: клик, просмотр, покупка
    event_type LowCardinality(String),
    -- сумма покупки
    amount Float64
)
-- Движок с поддержкой слияний
ENGINE = MergeTree()
-- Сортировка по пользователю и времени
ORDER BY (user_id, event_time)
-- Партиционирование по месяцам
PARTITION BY toYYYYMM(event_time)
-- Размер гранулы по умолчанию
SETTINGS index_granularity = 8192;

Что делает MergeTree

Данные в ClickHouse пишутся кусками, которые называются партами (parts). Вставка создаёт новый парт, а фоновые процессы постепенно сливают мелкие парты в крупные — отсюда и название движка. Вставка дешёвая, потому что ничего не перестраивается на лету: просто добавляется новый неизменяемый кусок данных.

Разреженный первичный индекс

Теперь ответим на вопрос, как ClickHouse так быстро находит нужные данные.

В PostgreSQL B-tree индекс знает адрес каждой строки. Если в таблице миллиард строк — в индексе миллиард записей. Это работает, но индекс занимает гигабайты памяти.

ClickHouse использует разреженный индекс. Он хранит по одной метке на каждые 8192 строки — эта группа называется гранулой. Для таблицы с миллиардом строк в индексе — это около 122 тысяч записей вместо миллиарда. Такой индекс целиком помещается в оперативную память, даже если данных на диске десятки терабайт.

Когда приходит запрос, база бинарным поиском находит нужные гранулы по индексу и дочитывает их целиком. Отсюда правило: ORDER BY определяет, какие запросы будут быстрыми. Если фильтруете по первой колонке в ORDER BY — индекс работает. Если по второй — индекс придётся прочитать целиком. И ещё: ORDER BY меняется только пересозданием таблицы, так что выбирать его нужно с умом.

Что происходит с UPDATE, DELETE и транзакциями

Во многих материалах по ClickHouse написано, что изменять данные в нём нельзя. Это устаревшая информация.

Ситуация изменилась в августе 2025 года. В релизе 25.7 привычный синтаксис UPDATE добрался до стабильной ветки. Механика следующая: строка не перезаписывается в существующем парте на месте. Вместо этого база создаёт компактный patch-парт с изменениями, а при фоновых слияниях патч применяется к основным данным. 

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

DELETE устроен похожим образом. Создаётся patch-парт, который помечает строку удалённой через служебное поле.

-- Обновление одной строки через lightweight UPDATE
UPDATE events
SET amount = 1500
WHERE user_id = 42 AND event_time = '2026-01-15 10:30:00';

Есть и ограничения. Откатить несколько операций одной командой здесь не получится: BEGIN и ROLLBACK не работают. Вставка блока атомарна — либо весь блок записался, либо ничего, но на этом гарантии заканчиваются. Первичный ключ база не проверяет на уникальность: две строки с одинаковым ключом лягут рядом. 

Для дедупликации есть движок ReplacingMergeTree — он схлопывает дубликаты во время фоновых слияний, но не сразу. И массовые точечные апдейты по одной строке остаются плохой идеей. Каждый такой запрос создаёт отдельный патч, фоновые слияния не успевают, и база начинает тормозить. Если задача требует частых изменений каждой строки, ClickHouse не подходит.

Полезный блок со скидкой

По промокоду: KOD (можно просто нажать) — вы получите скидку на все курсы Практикума.

Если хочется считать метрики и строить отчёты по миллионам строк, начните с курса Аналитик данных. Если интереснее та часть, где данные из PostgreSQL доезжают до ClickHouse, есть курс Инженер данных с нуля. А если вы уже пишете SQL и хотите проектировать хранилища и пайплайны для продакшена, посмотрите курс Инженер данных.

Бесплатные вводные курсы в Практикуме тоже есть — по всем направлениям, от Python до аналитики. 

Что меняется в SQL при переходе с PostgreSQL

Диалект SQL в ClickHouse похож на стандартный, поэтому запросы с GROUP BY переносятся почти без правок. Разница в деталях.

PostgreSQLClickHouse
BIGINTInt64
TEXTString
TEXT с малым числом уникальных значенийLowCardinality(String)
TIMESTAMPDateTime
DATE_TRUNC(‘month’, date)toStartOfMonth(date)
EXTRACT(YEAR FROM date)toYear(date)
COUNT(DISTINCT user_id)uniq(user_id)

Тип LowCardinality(String) — обёртка, которая применяет словарное кодирование к строкам с небольшим числом уникальных значений. Если уникальных значений меньше 10 тысяч, экономия места может быть в 3-10 раз.

Приближённые функции вроде uniq и quantile дают результат с небольшой погрешностью, но работают в разы быстрее и требуют меньше памяти. Для дашбордов и мониторинга uniqCombined даёт ошибку около 0,1% при втрое меньшем потреблении памяти, чем точный uniqExact.

Один и тот же аналитический запрос на двух диалектах.

PostgreSQL:

-- Выручка по месяцам за 2026 год
SELECT
    DATE_TRUNC('month', order_date) AS month,
    SUM(amount) AS revenue
FROM orders
WHERE order_date >= '2026-01-01'
GROUP BY month
ORDER BY month;

ClickHouse:

-- Выручка по месяцам за 2026 год
SELECT
    toStartOfMonth(order_date) AS month,
    sum(amount) AS revenue
FROM orders
WHERE order_date >= '2026-01-01'
GROUP BY month
ORDER BY month;

Синтаксис почти идентичный, но механика отличается: ClickHouse прочитает только две колонки — order_date и amount — вместо всех колонок таблицы.

Когда брать ClickHouse, а когда остаться на PostgreSQL

Есть класс задач, где ClickHouse экономит часы работы и нервы команды:

  • продуктовая аналитика на миллионах пользователей — клики, просмотры, конверсии, воронки по когортам;
  • логи и метрики мониторинга — каждое событие пишется отдельной строкой, а дашборд агрегирует их по часам и дням;
  • витрины для BI — аналитики строят отчёты, не трогая боевую базу приложения;
  • исторические срезы за годы — тренды и сравнения периодов считаются за секунды, а не за минуты.

С другими задачами ClickHouse только добавит хлопот:

  • интернет-магазин с корзиной и оплатой — нужны транзакции и мгновенные обновления статусов;
  • сервис, где строки часто меняются по одной — каждый апдейт создаёт патч, фоновые слияния не успевают;
  • база на десятки гигабайт — PostgreSQL справляется сам, а второй инструмент в проекте становится обузой;
  • справочники с жёсткими ограничениями целостности и внешними ключами — ClickHouse не проверяет ни уникальность, ни ссылочную целостность.

Порог, ниже которого затея не окупается, — миллион строк. На таких объёмах PostgreSQL отдаёт агрегаты достаточно быстро, а возня с новым кластером съест больше времени, чем сэкономит. Выигрыш начинается на десятках миллионов записей — там, где большие данные перестают помещаться в память одной машины и требуют особого подхода к хранению. 

Как подружить ClickHouse и PostgreSQL в одном проекте

В большинстве команд рабочая схема такая: PostgreSQL остаётся боевой базой приложения, ClickHouse принимает поток событий и обслуживает аналитику.

Связать их можно несколькими способами. Движок таблиц PostgreSQL позволяет делать SELECT и INSERT напрямую в удалённую базу PostgreSQL. Движок базы данных MaterializedPostgreSQL создаёт в ClickHouse копии таблиц PostgreSQL и синхронизирует изменения через логическую репликацию — это экспериментальная функция, но рабочая. 

Для ClickHouse Cloud рекомендуют использовать ClickPipes — сервис, который поддерживает высокопроизводительный CDC для PostgreSQL.

Для небольших объёмов подойдёт ночная пакетная выгрузка: скрипт забирает данные из PostgreSQL и заливает в ClickHouse. Просто, дёшево и достаточно, если аналитика не требует свежих данных в реальном времени.

Как запустить ClickHouse и попробовать самому

Для тех, кто хочет испытать ClickHouse на практике.

Поднять контейнер в Docker. Одна команда:

# Запускаем ClickHouse в Docker
docker run -d --name clickhouse-server \
  --ulimit nofile=262144:262144 \
  -p 8123:8123 \
  clickhouse/clickhouse-server

Зайти в clickhouse-client — командную строку для запросов:

# Подключаемся к контейнеру и открываем клиент
docker exec -it clickhouse-server clickhouse-client

Создать таблицу с MergeTree. Можно скопировать пример из раздела про индексы.

Залить открытый датасет и выполнить запрос. 

На сайте ClickHouse есть несколько демонстрационных наборов данных. Для эксперимента подойдёт датасет с данными о поездках на такси в Нью-Йорке — там несколько миллионов строк.

Если не хочется ничего ставить, есть онлайн-песочница по адресу sql.clickhouse.com. Там можно выполнять запросы прямо в браузере без установки. Для боевого запуска лучше взять управляемый сервис — например, в Yandex Cloud — чтобы не возиться с администрированием кластера.

Частые вопросы

ClickHouse заменяет PostgreSQL?

Нет. ClickHouse решает аналитические задачи, PostgreSQL — транзакционные. В большинстве проектов они работают вместе. Если вы готовитесь к вопросам по PostgreSQL на собеседовании, эти различия стоит держать в голове: интервьюеры любят спрашивать, почему для одной задачи выбрали OLTP-базу, а для другой — OLAP. 

Нужно ли знать ClickHouse джуну-аналитику?

Да, базовое понимание пригодится. SQL в ClickHouse похож на стандартный, а знание особенностей колоночного хранения помогает писать эффективные запросы. Для позиций, связанных с аналитикой данных, знакомство с ClickHouse — преимущество.

ClickHouse бесплатный?

Да, ClickHouse распространяется под лицензией Apache 2.0. Можно бесплатно скачать, установить и использовать. Платить придётся только за managed-сервисы, если не хочется администрировать самостоятельно.

Насколько ClickHouse быстрее PostgreSQL на аналитике?

На бенчмарке ClickBench с 100 миллионами строк ClickHouse занимает 9,26 ГиБ против примерно 100 ГиБ у PostgreSQL — разница в десять раз по объёму хранения. По скорости запросов разрыв тоже существенный, но зависит от конкретного запроса и схемы данных.

Вопрос выбора между ClickHouse и PostgreSQL сводится к профилю запросов и объёму данных, а не к моде на технологии. Если приложение пишет по одной строке и читает по одной строке — PostgreSQL. Если аналитика регулярно перелопачивает миллионы строк ради агрегатов — ClickHouse. В большинстве проектов нужны оба инструмента, каждый на своём месте.

Советуем почитать

Нормализация базы данных: 1НФ, 2НФ, 3НФ на примерах — как проектируют таблицы для транзакционной базы и почему в OLTP данные дробят, а в аналитике, наоборот, собирают в широкие таблицы.

Векторные базы данных: зачем они нужны для RAG — ещё один класс специализированных баз: как они хранят эмбеддинги и почему обычная СУБД с этой задачей не справляется.

MySQL на собеседовании: вопросы junior и middle — транзакции, индексы и типовые задачи на второй популярной OLTP-базе; пригодится, чтобы сравнить её с PostgreSQL.

SQLite — самая простая база данных, которая работает везде — встраиваемая база в одном файле: противоположный ClickHouse полюс и хороший пример того, что выбор СУБД зависит от задачи.

DevOps с нуля в 2026: что учить и как войти в профессию — контейнеры, инфраструктура и эксплуатация: всё, что понадобится, когда ClickHouse из Docker на ноутбуке переедет в кластер.

Бонус для читателей

С выбором базы разобрались. Теперь дело за практикой. Если хочется поработать с ClickHouse — поднять кластер, залить датасет и посмотреть, как миллионы строк агрегируются за секунды, — в Практикуме есть курсы по аналитике данных, backend-разработке и работе с базами. Промокод KOD даст скидку на любой платный курс — нажмите на него, чтобы выбрать программу. Бесплатные курсы тоже никуда не делись: начать можно в любой момент, карту привязывать не нужно.

Вам может быть интересно
medium