Партиционирование таблиц
Урок объясняет партиционирование — приём, который ускоряет запросы и упрощает перезагрузку данных.
Партиционирование (partitioning) — разбиение большой таблицы или набора файлов на части по значению ключа, чаще всего по дате.
Зачем резать данные на части
Таблица событий за три года — это миллиарды строк. Но почти любой запрос смотрит на узкий период: «события за вчера», «продажи за июнь». Если данные физически разложены по папкам-партициям date=2026-06-21/, движок прочитает только нужную партицию и пропустит остальные. Это называется partition pruning (отсечение партиций).
/events/
date=2026-06-20/part.parquet
date=2026-06-21/part.parquet ← запрос за 21-е читает только это
date=2026-06-22/part.parquetБонус для конвейеров
Партиции — лучший друг идемпотентности. Если конвейер за 21 июня нужно перезапустить (пришли исправленные данные), он просто перезаписывает партицию date=2026-06-21 целиком, не трогая остальные дни. Никаких дублей, никакой ручной чистки.
Эта связка партиций и идемпотентности — один из самых важных приёмов в дата-инженерии, и мы ещё вернёмся к ней в разделе про повторные запуски. Запомните пока главное: если данные физически разложены по дням, то «загрузка за день» и «перезагрузка за день» — это одна и та же безопасная операция перезаписи папки. Без партиций пришлось бы аккуратно удалять старые строки за дату перед вставкой новых, что куда сложнее и опаснее.
Как работает под капотом
В реляционной базе аналог — индекс или столбец-партиция, по которому фильтруют. Смоделируем «отсечение» через WHERE по дате и сравним с агрегацией по партициям.
CREATE TABLE events (id INTEGER PRIMARY KEY, day TEXT, kind TEXT);
INSERT INTO events VALUES
(1,'2026-06-20','click'), (2,'2026-06-20','view'),
(3,'2026-06-21','click'), (4,'2026-06-21','click'),
(5,'2026-06-22','view');
-- запрос за один день: движок отсекает остальные партиции
SELECT day, COUNT(*) AS cnt
FROM events
WHERE day = '2026-06-21'
GROUP BY day;Покажем логику выбора партиции на чистом Python — как конвейер раскладывает записи по «папкам».
from collections import defaultdict
rows = [("2026-06-20","a"), ("2026-06-21","b"), ("2026-06-21","c")]
partitions = defaultdict(list)
for day, val in rows:
partitions[f"date={day}"].append(val)
for part, items in sorted(partitions.items()):
print(part, "->", items)Вывод:
date=2026-06-20 -> ['a'] date=2026-06-21 -> ['b', 'c']
Частые ошибки
- Партиционировать по столбцу с тысячами значений. Партиция по
user_idсоздаст миллионы крошечных файлов — это убивает производительность. Партиционируют по дате или региону. - Слишком мелкие партиции. Партиции по часам при малом объёме данных дают много мелких файлов (small files problem).
- Забыть фильтр по ключу партиции. Если в запросе нет
WHERE date = ..., отсечение не сработает и читается всё.
Итог
- Партиционирование делит данные по ключу (обычно дате) на отдельные части.
- Partition pruning читает только нужные партиции, ускоряя запросы.
- Перезапись одной партиции — простой способ сделать загрузку идемпотентной.