Почти каждый проект начинается с PostgreSQL — и это правильно. Но рано или поздно приходит момент: аналитические запросы начинают тормозить, дашборды грузятся минутами, а команда говорит «давайте прикрутим ClickHouse». Разберём, когда это действительно нужно, а когда — лишняя сложность.
Почему PostgreSQL вообще начинает тормозить на аналитике
PostgreSQL хранит данные строками. Это удобно: если нужна одна запись — прочитали одну строку. Если нужно обновить поле — нашли строку, поменяли.
Но представьте аналитический запрос: «посчитай суммарную выручку по всем регионам за последние два года». PostgreSQL вынужден прочитать каждую строку целиком — даже если для ответа нужны только три поля из двадцати. На миллионах строк это становится медленным и нагружает диск.
ClickHouse хранит данные по столбцам. Для того же запроса он прочитает только нужные столбцы, пропустив остальные. Плюс данные в столбцах хорошо сжимаются — однотипные значения рядом. Результат: аналитические агрегаты на миллиардах строк за секунды.
Но это не повод заменять PostgreSQL. ClickHouse плохо работает с точечными запросами («дай мне конкретный заказ по ID»), почти не умеет обновлять отдельные записи и не поддерживает полноценные транзакции. Поэтому вопрос звучит не «что выбрать», а «когда добавить вторую базу рядом».
Какие запросы идут в PostgreSQL, а какие — в ClickHouse
PostgreSQL — это OLTP (Online Transaction Processing). Его сильные стороны:
- точечные чтения и записи («добавить заказ», «найти пользователя по email»);
- транзакции — несколько операций как одно целое;
- обновления и удаления записей;
- сложные связи между таблицами через JOIN.
ClickHouse — это OLAP (Online Analytical Processing). Его сильные стороны:
- агрегаты по огромным объёмам:
GROUP BYрегион/месяц/категория; - сканирование сотен миллионов и миллиардов строк за секунды;
- хранение событий и журналов годами при минимальной стоимости;
- параллельные запросы от аналитиков и BI-инструментов.
Хороший признак «ClickHouse-запроса»: он смотрит на весь период, считает агрегаты, никого не интересует конкретная строка. Хороший признак «PostgreSQL-запроса»: нужна конкретная запись, или данные нужно сразу же изменить.
Когда PostgreSQL справляется сам
Прежде чем добавлять новый компонент, стоит убедиться, что PostgreSQL действительно упёрся в потолок.
Несколько десятков миллионов строк — для PostgreSQL это немного. Правильные индексы и партиционирование по дате решают большинство задач.
Отчёты строит сам сервис и только несколько фиксированных запросов — тут PostgreSQL с репликой для чтения вполне хватит. Реплика принимает аналитические запросы и не мешает основной базе.
Данные меняются — заказы, балансы, остатки. ClickHouse создан для событий, которые вставили и больше не трогают; правки задним числом в нём болезненны.
Команда небольшая, и некому обслуживать второй stateful-компонент. Это честный аргумент отложить ClickHouse — пайплайн данных, мониторинг, резервные копии — всё это новые обязанности.
Признаки, что пора переходить к двум базам
Несколько сигналов, что PostgreSQL начинает мешать:
Объём данных. Аналитические таблицы перевалили за 50–100 миллионов строк или ежедневно прирастают на миллионы. Отчёты занимают минуты.
Характер запросов. Аналитика — это агрегаты за месяц или год, воронки, перцентили, уникальные пользователи. Не списки записей с фильтрами, а «посчитай за период».
Аналитики мешают проду. Команда данных или BI-инструменты запускают произвольные запросы, которые нагружают базу и замедляют продуктовых пользователей. Или их приходится запрещать, чтобы не мешали.
Долгая история. Нужно хранить события годами: клики, просмотры, статусы. ClickHouse сжимает такие данные в 5–20 раз, и длинная история перестаёт дорого стоить.
Свежесть данных не критична. Дашборды с данными «на пять минут назад» устраивают всех потребителей. ClickHouse получает данные с небольшим лагом через пайплайн, мгновенной синхронизации нет.
Как данные попадают из PostgreSQL в ClickHouse
Это ключевой вопрос, который часто упускают. Нельзя просто «писать в две базы» — это рецепт рассинхронизации.
Правильная схема: пайплайн через очередь.
- Сервис пишет только в PostgreSQL. Изменения фиксируются в outbox-таблице или через CDC (Change Data Capture).
- Kafka забирает события из PostgreSQL.
- Потребитель читает из Kafka и пишет в ClickHouse пакетами.
Лаг такого пайплайна — обычно секунды или минуты. Зато данные согласованы: если запись прошла в PostgreSQL, она рано или поздно окажется в ClickHouse. Детально это описано в статье про интеграцию пайплайна.
Схема в ClickHouse при этом другая, чем в PostgreSQL: денормализованные таблицы, события, предагрегаты — то, что ускоряет аналитические запросы. Просто перелить нормализованную схему PostgreSQL «как есть» и потом удивляться медленным JOIN-ам — распространённая ошибка.
Типичные ошибки
«Заменить PostgreSQL на ClickHouse». Перенести в ClickHouse заказы, балансы и остатки — и обнаружить, что нет транзакций, дешёвых обновлений и точечных чтений. ClickHouse — дополнение, основное хранилище остаётся в PostgreSQL.
Слишком рано. Развернуть шардированный кластер ClickHouse под пять миллионов строк, которые PostgreSQL прожевал бы с одним индексом. Лишний компонент и пайплайн — ради проблемы, которой ещё нет.
Писать в обе базы прямо из кода. Два вызова подряд — в PostgreSQL и ClickHouse — внутри одного действия. Если второй упадёт, данные разойдутся. Нужен пайплайн через очередь.
Перенести нормализованную схему как есть. ClickHouse не умеет в JOIN так, как PostgreSQL. Схема проектируется от аналитических запросов: денормализация, события, агрегаты.
Принять реплику PostgreSQL за OLAP. Реплика снимает нагрузку чтения с основной базы, но не делает строчное хранение колоночным. Тяжёлый запрос за два года будет так же медленным. Реплика — промежуточный шаг, не конечная точка.
Коротко
- PostgreSQL хранит строками — быстро для точечных операций. ClickHouse хранит столбцами — быстро для аналитических агрегатов.
- ClickHouse не заменяет PostgreSQL, а дополняет: PostgreSQL держит домен и транзакции, ClickHouse — события и аналитику.
- Пора задуматься о ClickHouse, если аналитические таблицы в сотнях миллионов строк, запросы — агрегаты за длинный период, аналитики мешают проду.
- Данные передаются через пайплайн (outbox → Kafka → потребитель), а не двойной записью из кода.
- Схема в ClickHouse строится от аналитических запросов, а не копируется из PostgreSQL.
- Держать две базы — это новые операционные обязанности. Если команда маленькая, лучше дольше оставаться в PostgreSQL с правильными индексами и репликой.
Что почитать дальше
- Как устроен ClickHouse — почему он такой быстрый и чем за это платят.
- Интеграция: пайплайн PG → Kafka → ClickHouse — outbox, CDC и потребитель.
- PostgreSQL или MongoDB — выбор основного хранилища.
- Поиск: PG FTS или Elasticsearch — похожая развилка для поисковой нагрузки.