UpPetto

This is a real course generated by UpPetto — unedited.

AI-generated · source-grounded review: written by two AI models, cross-checked by a third. Yours takes ~5 minutes.

Create my own course

Партиционирование и работа с датами

Pareto core

Партиционирование — это разделение большой таблицы на меньшие физические части (партиции) по определенному критерию, чаще всего по дате. Для аналитика это означает одно: правильный запрос сканирует только нужные партиции, игнорируя остальные, что дает ускорение в десятки и сотни раз.

Как работает партиционирование

Представьте таблицу events с миллиардом строк за 3 года. Без партиционирования любой запрос, даже за один день, потенциально сканирует все строки. С партиционированием по месяцам таблица физически разделена на 36 частей:

events_2022_01  (январь 2022)
events_2022_02  (февраль 2022)
...
events_2024_12  (декабрь 2024)

Когда вы запрашиваете данные за январь 2024, СУБД читает только партицию events_2024_01 — примерно 1/36 от всей таблицы. Это называется partition pruning (отсечение партиций).

Критическое правило: всегда фильтруйте по дате

Партиционирование работает только если вы явно указываете фильтр по столбцу партиционирования в WHERE. Без этого СУБД сканирует все партиции.

Плохо — сканируются все партиции:

SELECT user_id, COUNT(*) AS event_count
FROM events
WHERE event_type = 'purchase'
GROUP BY user_id;

Даже если таблица партиционирована по event_date, этот запрос прочитает все 36 партиций (миллиард строк), потому что нет фильтра по дате.

Хорошо — сканируется одна партиция:

SELECT user_id, COUNT(*) AS event_count
FROM events
WHERE event_date >= '2024-01-01' 
  AND event_date < '2024-02-01'
  AND event_type = 'purchase'
GROUP BY user_id;

Теперь СУБД читает только партицию января 2024 (~28 млн строк вместо миллиарда) — ускорение в 35 раз.

Проверка использования партиций через EXPLAIN

EXPLAIN
SELECT COUNT(*)
FROM events
WHERE event_date = '2024-01-15';

В плане выполнения ищите строки вроде:

Seq Scan on events_2024_01  (cost=0.00..15234.00 rows=50000)

Если видите только одну партицию (events_2024_01) — отлично, partition pruning работает. Если видите все партиции (events_2022_01, events_2022_02, ...) — фильтр по дате отсутствует или написан неправильно.

Типичные ошибки при работе с партициями

Ошибка 1: Функции в условии фильтра

-- Партиции НЕ отсекаются
WHERE DATE(event_timestamp) = '2024-01-15'

-- Партиции отсекаются
WHERE event_timestamp >= '2024-01-15 00:00:00' 
  AND event_timestamp < '2024-01-16 00:00:00'

Применение функции к столбцу партиционирования мешает СУБД определить нужные партиции. Всегда используйте диапазоны без функций.

Ошибка 2: Слишком широкий диапазон

Если вам нужны данные за неделю, не запрашивайте год:

-- Плохо: сканируется 12 партиций
WHERE event_date >= '2024-01-01' AND event_date < '2024-12-31'

-- Хорошо: сканируется 1 партиция
WHERE event_date >= '2024-01-15' AND event_date < '2024-01-22'

Чем уже диапазон дат, тем меньше партиций читается.

Ошибка 3: Забытый фильтр в JOIN

-- Плохо: обе таблицы сканируются полностью
SELECT e.user_id, u.name, COUNT(*) AS event_count
FROM events e
JOIN users u ON e.user_id = u.user_id
GROUP BY e.user_id, u.name;

-- Хорошо: events сканируется только за нужный период
SELECT e.user_id, u.name, COUNT(*) AS event_count
FROM events e
JOIN users u ON e.user_id = u.user_id
WHERE e.event_date >= '2024-01-01' AND e.event_date < '2024-02-01'
GROUP BY e.user_id, u.name;

Практические рекомендации

1. Узнайте схему партиционирования

Спросите у команды данных или DBA: - По какому столбцу партиционирована таблица? (обычно дата) - Какая гранулярность? (день, месяц, год) - Как называются партиции?

В PostgreSQL можно посмотреть:

SELECT tablename 
FROM pg_tables 
WHERE tablename LIKE 'events_%'
ORDER BY tablename;

2. Делайте фильтр по дате привычкой

Для любой большой партиционированной таблицы (логи, события, транзакции) первое условие в WHERE — всегда диапазон дат:

WHERE event_date >= '2024-01-01' AND event_date < '2024-02-01'
  AND ... -- остальные условия

3. Используйте параметры для динамических дат

-- Последние 7 дней
WHERE event_date >= CURRENT_DATE - INTERVAL '7 days'

-- Текущий месяц
WHERE event_date >= DATE_TRUNC('month', CURRENT_DATE)
  AND event_date < DATE_TRUNC('month', CURRENT_DATE) + INTERVAL '1 month'

4. Комбинируйте с индексами

Партиционирование ускоряет сканирование по дате, но внутри партиции все еще может быть миллион строк. Индексы на других столбцах (user_id, event_type) внутри каждой партиции дополнительно ускорят запросы.

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

AI-generated · source-grounded review

Automated fact-check did not complete for this lesson — do not rely on it as verified.

A second opinion has not checked this lesson.

Key concepts: партиционирование фильтрация по датам сканирование партиций
Tell me more 🔒 Didn't understand — explain simply 🔒 Show examples 🔒 Sources 🔒

On your own course these buttons answer instantly, quizzes track what you've mastered, and lessons adapt to your gaps. Sign up free →

Check yourself

1. Что такое partition pruning (отсечение партиций)?
2. Почему запрос WHERE DATE(event_timestamp) = '2024-01-15' не использует отсечение партиций?
3. Что произойдет, если запросить данные из партиционированной таблицы без фильтра по столбцу партиционирования?
Sign up free to check your answers