ClickHouse vs PostgreSQL: когда нужна колоночная СУБД

Когда PostgreSQL недостаточно для аналитики

PostgreSQL — отличная OLTP-СУБД, оптимизированная для транзакций: вставка, обновление, удаление отдельных строк. Но когда аналитический запрос сканирует миллионы строк по нескольким колонкам, строковое хранилище PostgreSQL читает все колонки каждой строки — даже если запросу нужны только 3 из 50.

ClickHouse — колоночная СУБД от Яндекса, спроектированная для OLAP-нагрузок. Данные хранятся по колонкам: при запросе SELECT avg(amount) FROM orders WHERE date > '2024-01-01' считываются только колонки amount и date, а не вся строка. Это даёт прирост скорости в 10-100 раз на аналитических запросах по таблицам с миллиардами строк.

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

Архитектурные различия: строки vs колонки

В строковом хранилище (PostgreSQL) данные записываются по строкам:

-- Физическое хранение PostgreSQL (упрощённо)
[id=1, name="Иванов", amount=5000, date="2024-01-15"]
[id=2, name="Петров", amount=3200, date="2024-01-16"]
[id=3, name="Сидоров", amount=7800, date="2024-01-16"]

В колоночном хранилище (ClickHouse) данные группируются по колонкам:

-- Физическое хранение ClickHouse (упрощённо)
id:     [1, 2, 3, ...]
name:   ["Иванов", "Петров", "Сидоров", ...]
amount: [5000, 3200, 7800, ...]
date:   ["2024-01-15", "2024-01-16", "2024-01-16", ...]

Преимущества колоночного подхода для аналитики:

  • Сжатие: однотипные данные в одной колонке сжимаются в 5-20 раз эффективнее (LZ4, ZSTD)
  • Vectorized execution: операции применяются к целым блокам значений, используя SIMD-инструкции CPU
  • Меньше I/O: читаются только нужные колонки, остальные пропускаются

Установка ClickHouse и создание таблиц

Устанавливаем ClickHouse на Ubuntu:

sudo apt install -y apt-transport-https ca-certificates curl
curl -fsSL https://packages.clickhouse.com/rpm/lts/repodata/repomd.xml.key | \
    sudo gpg --dearmor -o /usr/share/keyrings/clickhouse-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/clickhouse-keyring.gpg] \
    https://packages.clickhouse.com/deb stable main" | \
    sudo tee /etc/apt/sources.list.d/clickhouse.list

sudo apt update
sudo apt install -y clickhouse-server clickhouse-client

sudo systemctl enable --now clickhouse-server

Создаём таблицу для аналитики (движок MergeTree):

CREATE TABLE events (
    event_date Date,
    event_time DateTime,
    user_id UInt64,
    event_type LowCardinality(String),
    page_url String,
    duration_ms UInt32,
    country LowCardinality(String),
    device LowCardinality(String)
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_type, user_id, event_time)
TTL event_date + INTERVAL 365 DAY
SETTINGS index_granularity = 8192;

Ключевые элементы: PARTITION BY для управления хранением (можно удалять старые партиции), ORDER BY определяет физическую сортировку и первичный индекс, TTL — автоматическое удаление устаревших данных.

Сравнение производительности на реальных запросах

Тестовый набор: таблица событий с 500 млн строк, 8 колонок. Сервер: 16 ядер, 64 ГБ RAM, NVMe SSD.

ЗапросPostgreSQLClickHouseУскорение
COUNT(*) с фильтром по дате45 сек0.15 сек300x
GROUP BY по дням за месяц120 сек0.8 сек150x
DISTINCT пользователей за период90 сек1.2 сек75x
TOP-100 страниц по просмотрам180 сек2.1 сек86x
INSERT одной строки0.5 мс50 мс*0.01x

*ClickHouse оптимизирован для пакетной вставки (тысячи строк за раз), а не для одиночных INSERT. Рекомендуется вставлять данные батчами по 1000-100000 строк.

Примеры аналитических запросов ClickHouse

ClickHouse поддерживает расширенный SQL с мощными аналитическими функциями:

-- Количество уникальных пользователей по дням
SELECT
    event_date,
    uniqExact(user_id) AS unique_users,
    count() AS total_events
FROM events
WHERE event_date >= '2024-01-01'
GROUP BY event_date
ORDER BY event_date;

-- Перцентили времени загрузки
SELECT
    event_type,
    quantile(0.50)(duration_ms) AS p50,
    quantile(0.95)(duration_ms) AS p95,
    quantile(0.99)(duration_ms) AS p99
FROM events
WHERE event_date = today()
GROUP BY event_type;

-- Retention: доля вернувшихся пользователей
SELECT
    first_date,
    countIf(return_date = first_date + 1) / count() AS day1_retention,
    countIf(return_date = first_date + 7) / count() AS day7_retention
FROM (
    SELECT user_id, min(event_date) AS first_date
    FROM events GROUP BY user_id
) AS first
INNER JOIN (
    SELECT DISTINCT user_id, event_date AS return_date FROM events
) AS ret USING user_id
GROUP BY first_date;

Загрузка данных из PostgreSQL в ClickHouse

Для гибридной архитектуры (OLTP в PostgreSQL, аналитика в ClickHouse) настройте репликацию данных. Самый простой способ — встроенный движок PostgreSQL:

-- Внешняя таблица, ссылающаяся на PostgreSQL
CREATE TABLE pg_orders
    ENGINE = PostgreSQL('pg-server:5432', 'production', 'orders', 'readonly', 'password');

-- Копирование данных в ClickHouse-таблицу
INSERT INTO ch_orders
    SELECT * FROM pg_orders WHERE created_at >= '2024-01-01';

Для потоковой репликации используйте MaterializedPostgreSQL (экспериментальный движок):

CREATE DATABASE pg_replica
ENGINE = MaterializedPostgreSQL('pg-server:5432', 'production', 'replicator', 'password')
SETTINGS materialized_postgresql_tables_list = 'orders,users,events';

Альтернативные инструменты для ETL: Airbyte, dbt (для трансформаций), Debezium + Kafka (CDC). Для однократного импорта больших объёмов эффективен CSV-формат:

# Экспорт из PostgreSQL
psql -h pg-server -U readonly -d production -c \
    "COPY (SELECT * FROM events WHERE date > '2024-01-01') TO STDOUT WITH CSV" \
    | clickhouse-client --query="INSERT INTO events FORMAT CSV"

Когда НЕ использовать ClickHouse

ClickHouse — не универсальная СУБД. Он не подходит для:

  • OLTP-нагрузок: частые UPDATE и DELETE отдельных строк. ClickHouse поддерживает мутации (ALTER TABLE UPDATE/DELETE), но они выполняются асинхронно и перезаписывают целые партиции
  • Транзакций: нет поддержки ACID-транзакций в классическом смысле. Нет ROLLBACK
  • Ключ-значение: запросы по единственной строке (SELECT * WHERE id = 123) работают медленнее, чем в PostgreSQL
  • Малых данных: если в таблице менее 1 млн строк, PostgreSQL с правильными индексами будет не медленнее

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

Мониторинг и обслуживание ClickHouse

ClickHouse предоставляет системные таблицы для мониторинга:

-- Текущие запросы
SELECT query, elapsed, read_rows, memory_usage
FROM system.processes;

-- Медленные запросы за последний час
SELECT query, query_duration_ms, read_rows, result_rows
FROM system.query_log
WHERE event_date = today()
    AND query_duration_ms > 5000
ORDER BY query_duration_ms DESC
LIMIT 10;

-- Размер таблиц
SELECT
    table,
    formatReadableSize(sum(bytes_on_disk)) AS disk_size,
    sum(rows) AS total_rows,
    count() AS parts
FROM system.parts
WHERE active
GROUP BY table
ORDER BY sum(bytes_on_disk) DESC;

Для продакшена настройте max_memory_usage (лимит памяти на запрос), max_execution_time (таймаут) и профили пользователей с ограничениями ресурсов.

Часто задаваемые вопросы

Нет. ClickHouse не поддерживает ACID-транзакции, UPDATE/DELETE отдельных строк выполняются как тяжёлые мутации. Используйте ClickHouse как аналитический слой поверх транзакционной СУБД (PostgreSQL, MySQL).

При правильной схеме и сжатии — десятки терабайт сырых данных на одном сервере. Сжатие колоночного хранилища (LZ4/ZSTD) обычно даёт коэффициент 5-15x. Для горизонтального масштабирования используйте шардирование через Distributed-таблицы.

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

Используйте ReplicatedMergeTree с ZooKeeper (или ClickHouse Keeper) для репликации данных между серверами. Минимальная отказоустойчивая конфигурация: 2 реплики + 3 ноды ClickHouse Keeper. Шардирование + репликация дают и масштабируемость, и отказоустойчивость.

Нужна помощь с настройкой?

Специалисты АйТи Фреш помогут с внедрением и настройкой — 15+ лет опыта, обслуживание от 15 000 ₽/мес

📞 Связаться с нами
#clickhouse vs postgresql#колоночная СУБД#clickhouse настройка#аналитическая база данных#clickhouse запросы#OLAP база данных#clickhouse установка#postgresql аналитика
Комментарии 0

Оставить комментарий

загрузка...