Что такое OLAP
OLAP — Online Analytical Processing. Это базы данных, обслуживающие аналитические запросы: агрегации по миллиардам строк, JOIN-ы огромных таблиц, отчёты, дэшборды, исследовательские запросы аналитиков. В противоположность OLTP, где главное — много мелких операций, OLAP оптимизирован под мало запросов, каждый из которых сканирует и обрабатывает большие объёмы.
Канонические примеры OLAP-систем 2026 года:
- Snowflake — облачный DWH, market leader.
- Google BigQuery — serverless DWH в GCP.
- Amazon Redshift — DWH в AWS, исторически на базе ParAccel.
- ClickHouse — open-source OLAP от Yandex, фокус на скорости.
- Databricks SQL — lakehouse engine поверх Spark/Delta.
- DuckDB — in-process OLAP, “SQLite для аналитики”.
- Apache Druid / Pinot — real-time OLAP для дашбордов.
Все они построены вокруг тех же идей: колоночное хранение + параллельное выполнение + минимум индексов + денормализация.
Три кита OLAP
1. Колоночное хранение (columnar)
Мы разобрали это в модуле 5. В OLAP-системах данные физически хранятся по колонкам, что даёт:
- Projection pushdown: читаем только нужные колонки (из 100 — реально 3-5).
- Predicate pushdown: по min/max в блоках пропускаются неподходящие данные.
- Компрессия 10-20x: однородные данные сжимаются великолепно.
- Vector processing: CPU обрабатывает массив значений за такт через SIMD.
2. MPP — Massively Parallel Processing
OLAP-движки распараллеливают запрос на много машин и/или ядер. Запрос разбивается на стадии, каждая стадия выполняется параллельно множеством worker-ов.
-- Этот запрос на 100 млрд строк
SELECT country, SUM(amount) FROM orders GROUP BY country;
-- В MPP-движке выполняется так:
-- 1. Каждый worker сканирует свою часть данных
-- 2. Каждый делает локальную агрегацию по country
-- 3. Результаты shuffle-ятся между worker-ами по hash(country)
-- 4. Финальная агрегация
-- 5. Сбор результата
Snowflake под капотом — это распределённая система с разделёнными storage (S3) и compute (warehouses). Можно поднять virtual warehouse на 4, 16, 64 узла, и тот же запрос выполняется во столько же раз быстрее (до определённого предела, ограниченного законом Амдала).
ClickHouse использует MPP внутри одного сервера (через много ядер) и distributed tables между серверами. BigQuery — фундаментально serverless, ты не управляешь slot-ами явно, движок сам параллелит на тысячах CPU.
Запрос разбивается на стадии, каждая исполняется параллельно
3. Денормализация
В отличие от OLTP, в OLAP таблицы намеренно денормализованы. Зачем — три причины:
- Меньше JOIN-ов. На миллиардах строк JOIN — самая дорогая операция. Если можно избежать — нужно избегать.
- Локальность. Все данные одной строки рядом, не нужно гоняться за foreign key-ами.
- Колоночная компрессия отлично работает на широких таблицах. Денормализованная wide table в Parquet/ClickHouse занимает не сильно больше нормализованной.
Типичная dimensional model (модуль 8):
- Один большой fact table с метриками (orders с amounts, customer_id, product_id, date).
- Несколько dimension tables с контекстом (customers, products, dates).
- Star schema — один уровень JOIN-ов.
Или ещё более экстремально — One Big Table (OBT): вообще без JOIN-ов, все поля включены в одну широкую таблицу. На ClickHouse это часто самый быстрый вариант.
Что НЕ нужно в OLAP
Минимум индексов
OLTP стоит на индексах. OLAP — почти без индексов. Причины:
- Сканы всё равно колоночные и parallelизованные, B-tree lookup на 1 миллиард строк не выигрывает у parallel scan.
- Индексы дороги в обслуживании при больших объёмах INSERT.
- Predicate pushdown через columnar statistics заменяет грубое skipping.
Snowflake не позволяет создать индекс вообще (есть micro-partitions с automatic clustering). ClickHouse имеет sparse primary index — это не B-tree, это разреженная structure для skipping. BigQuery — то же, кластеризация по колонкам, не индексы.
Малое внимание к транзакциям
OLAP-системы поддерживают транзакции, но это редко используется. Типичный workload — batch loads: раз в час/день большой COPY INTO. Internal операции (CTAS, INSERT INTO … SELECT) транзакционные, но точечных UPDATE-ов почти нет.
Snowflake поддерживает ACID, но isolation — Snapshot Isolation, концептуально похожая на READ COMMITTED. Никакого SERIALIZABLE с блокировками, и это нормально — никто не делает 1000 параллельных UPDATE одной строки в OLAP.
Нет UPDATE/DELETE на горячем пути
ClickHouse исторически не поддерживал UPDATE/DELETE вообще (только append-only + delayed mutations). В 2022-2024 добавили lightweight DELETE и UPDATE, но в production советуют использовать через ReplacingMergeTree.
Snowflake/BigQuery поддерживают UPDATE/DELETE, но они дорогие — переписывается целая micro-partition. Никто не делает UPDATE WHERE id = X тысячу раз в секунду.
Что делает OLAP быстрым
Сложим всё в одной картине. Запрос:
SELECT country, COUNT(*), SUM(amount)
FROM orders
WHERE event_date BETWEEN '2026-01-01' AND '2026-01-31'
GROUP BY country
ORDER BY SUM(amount) DESC
LIMIT 10;
На 100 млрд строк OLTP (Postgres) — это часы. ClickHouse/Snowflake — секунды. Почему:
- Columnar storage: читаются только 3 колонки (country, amount, event_date) из 30-100.
- Partition pruning: данные партиционированы по дате, читается только январь 2026.
- Predicate pushdown: внутри партиций — skipping блоков по statistics.
- Compression: даже эти 3 колонки сжаты в 10x.
- Parallel scan: 16-64 worker сканят данные одновременно.
- Vectorized processing: CPU обрабатывает 1024 значения за один cycle через SIMD.
- Distributed aggregation: партиальные суммы делаются локально, shuffle минимизирован.
В сумме: вместо чтения 100 GB+ из disk-а — реально читается 100 MB, обрабатывается за секунды.
Реальные числа
Один типичный benchmark (TPC-H, 1 TB):
- Postgres (OLTP): час+ на сложные TPC-H запросы.
- Snowflake (medium warehouse): 5-30 секунд.
- BigQuery: 3-15 секунд.
- ClickHouse (4-node): 1-5 секунд.
На bigger workloads (10 TB+, реальные production данные с реальными сложностями) разница в 50-500x ставит вопрос архитектуры однозначно: для аналитики — OLAP, никаких компромиссов.
Денормализация: пример
Возьмём те же orders из прошлого урока. В OLTP-Postgres схема нормализованная:
-- Postgres OLTP схема
CREATE TABLE customers (customer_id BIGINT PRIMARY KEY, name TEXT, country TEXT, ...);
CREATE TABLE products (product_id BIGINT PRIMARY KEY, name TEXT, category TEXT, price NUMERIC);
CREATE TABLE orders (order_id BIGINT PRIMARY KEY, customer_id BIGINT, product_id BIGINT, qty INT, created_at TIMESTAMP);
Для аналитического запроса “продажи по странам и категориям” нужен JOIN трёх таблиц.
В OLAP-ClickHouse — flat OBT:
-- ClickHouse OBT схема
CREATE TABLE orders_flat (
order_id UInt64,
customer_id UInt64,
customer_name String,
customer_country LowCardinality(String),
product_id UInt64,
product_name String,
product_category LowCardinality(String),
product_price Decimal(10, 2),
qty UInt32,
amount Decimal(12, 2),
created_at DateTime
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(created_at)
ORDER BY (created_at, customer_id);
Тот же запрос — без JOIN-ов, чистый scan. ClickHouse LowCardinality даёт автоматическое dictionary encoding для country и category — несколько байт на значение.
Ценой денормализации: при изменении имени клиента нужно обновить миллионы строк. В OLAP это допустимо, потому что:
- Имя клиента меняется редко.
- Обновление идёт батчем, не в real-time.
- Данные в OLAP всё равно derived от OLTP — переэкспортируется из источника.
OLAP-системы по типам
Cloud DWH, lakehouse, real-time OLAP, in-process
Snowflake, BigQuery, RedshiftCloud DWH: Snowflake, BigQuery, Redshift. Полностью managed, separated storage/compute, эластичное масштабирование. Дорого, но просто. Для большинства enterprise аналитики
Databricks, Trino, AthenaLakehouse: Databricks SQL, Trino/Athena over Iceberg/Delta. Storage в open format (Parquet) на S3/GCS, compute поверх. Дешевле, гибче, более complex
ClickHouse, Druid, PinotReal-time OLAP: ClickHouse, Druid, Pinot. Sub-second queries, real-time ingestion. Для user-facing dashboards, observability, ad-tech
DuckDB, MotherDuckIn-process: DuckDB, MotherDuck. SQLite-like, embedded в Python/notebook. Для аналитики до 100 GB на локальной машине или single-node cloud
Когда использовать каждый класс
- До 100 GB, individual analyst -> DuckDB на ноутбуке. Бесплатно, мгновенно, никаких infra.
- Enterprise data warehouse, любая команда -> Snowflake или BigQuery. Удобно, дорого, full-feature.
- Огромные объёмы, готовы к operating overhead -> Lakehouse (Databricks или Trino over Iceberg).
- Real-time дашборды для пользователей -> ClickHouse или Druid. Sub-second latency.
- Ad-hoc на data lake -> Athena/Trino, serverless поверх Parquet.
Углубление в clickhouse-course, sql-fundamentals, и модуль 15 (cloud data platforms).
Попробуй сам
- Установи DuckDB (
pip install duckdb). Скачай NYC Taxi data (1 файл за месяц). Сравни:- Загрузка в Postgres + агрегационный запрос
- DuckDB на Parquet + тот же запрос
- Создай Snowflake/BigQuery trial аккаунт. Загрузи open dataset (TPC-H). Запусти TPC-H query 1 на разных размерах warehouse.
- Развороти ClickHouse локально (Docker). Создай MergeTree таблицу с миллиардом строк. Замерь время GROUP BY запросов.
- Сравни планы выполнения одного запроса в Postgres и DuckDB через EXPLAIN. Найди ключевые различия (Seq Scan vs Vectorized, B-tree lookup vs Min-Max skipping).