Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Вложенное партиционирование в хранилищах данных
Вложенное партиционирование (composite partitioning) — это когда таблица разбивается по нескольким ключам одновременно. Да, разница существенная.
Типы партиционирования
Простое партиционирование
-- Партиционирование только по дате
CREATE TABLE events (
id BIGINT,
event_type VARCHAR,
created_at DATE,
user_id BIGINT
)
PARTITION BY RANGE (created_at) (
PARTITION p_2026_01 VALUES LESS THAN (2026-02-01),
PARTITION p_2026_02 VALUES LESS THAN (2026-03-01),
PARTITION p_2026_03 VALUES LESS THAN (2026-04-01)
);
Вложенное партиционирование
-- Партиционирование по дате И регионам
CREATE TABLE events (
id BIGINT,
region VARCHAR,
created_at DATE,
user_id BIGINT
)
PARTITION BY RANGE (created_at)
SUBPARTITION BY LIST (region) (
PARTITION p_2026_01 VALUES LESS THAN (2026-02-01) (
SUBPARTITION p_2026_01_us VALUES IN (US),
SUBPARTITION p_2026_01_eu VALUES IN (EU),
SUBPARTITION p_2026_01_as VALUES IN (AS)
),
PARTITION p_2026_02 VALUES LESS THAN (2026-03-01) (
SUBPARTITION p_2026_02_us VALUES IN (US),
SUBPARTITION p_2026_02_eu VALUES IN (EU),
SUBPARTITION p_2026_02_as VALUES IN (AS)
)
);
Ключевые разницы
1. Pruning (отсечение партиций)
Простое партиционирование:
-- Отсечение: только январские данные
SELECT * FROM events WHERE created_at = 2026-01-15;
-- Сканирует: 1 партицию
Вложенное партиционирование:
-- Двойное отсечение: январь И US
SELECT * FROM events WHERE created_at = 2026-01-15 AND region = US;
-- Сканирует: 1 субпартицию (вместо 3 при простом партиционировании)
2. Размер партиций
- Простое: каждая партиция по дате может быть 1-10 GB (весь мир)
- Вложенное: каждая субпартиция 100-500 MB (только один регион)
Меньше размер = быстрее поиск, лучше cache hit rate.
3. Управление метаданными
- Простое: 12 партиций за год
- Вложенное: 12 × 3 = 36 субпартиций
ОС нужно хранить больше информации о структуре.
Когда использовать
Используй вложенное:
-- Большие таблицы (> 100 GB)
-- Запросы часто фильтруют по двум ключам
SELECT COUNT(*) FROM orders
WHERE order_date >= 2026-03-01 AND country = RU;
Используй простое:
-- Таблицы < 50 GB
-- Запросы фильтруют по одному ключу
SELECT COUNT(*) FROM logs WHERE log_date = 2026-03-26;
Практический пример в PostgreSQL
PostgreSQL не поддерживает встроенное вложенное партиционирование, но можно эмулировать:
-- Основная таблица (только по дате)
CREATE TABLE events_2026_03 PARTITION OF events
FOR VALUES FROM (2026-03-01) TO (2026-04-01);
-- Субтабли (по регионам внутри месяца)
CREATE TABLE events_2026_03_us PARTITION OF events_2026_03
FOR VALUES IN (US);
CREATE TABLE events_2026_03_eu PARTITION OF events_2026_03
FOR VALUES IN (EU);
Минусы вложенного партиционирования
- Сложность управления — больше партиций = больше скриптов для maintenance
- Медленнее вставки — нужно определить две координаты
- Фрагментация — если распределение неравномерно (например, 90% данных в одном регионе)
Вывод
Вложенное партиционирование эффективно для больших систем с множественными фильтрами, но требует тщательного планирования. На практике я использую его, когда таблица превышает 500 GB и запросы регулярно фильтруют по двум ключам одновременно.
Похожие вопросы
- Какова роль NameNode в Hadoop и какие проблемы с ним связаны?
- Как обеспечить высокую доступность NameNode в Hadoop?
- Как работает кэширование в Spark? Когда его применять?
- Когда может быть выгодно переходить с Azure functions на что-то другое?
- Как адаптировать модель данных под новые требования (например, реферальную программу)?
- Как определять какие данные в какой шард идут?
- Хорошо ли закидывать булевые поля в индекс
- Как оценить алгоритмическую сложность индекса?
- Какие типы join-операций существуют в Spark и когда применять каждый?
- Что такое broadcast join в Spark и когда его использовать?
- Какой Select работает быстрее в greenplum или MS Sql при идентичных таблицах?
- Как взаимодействуют Spark, Hadoop и Hive при чтении/записи таблиц через Spark SQL?
- По какой схеме можно выделять ресурсы
- Что происходит под капотом при выполнении shuffle в Spark?
- Что нужно делать когда нагрузка на бд становится слишком большая?
- Как решал проблемы с памятью в Spark?
- Какой способ доставки был в вашей системе (at least once, at most once, excactly once)?
- Как бы организовал процесс интеграции с новой системой?
- Как диагностировать падение Spark-приложения после запуска?
- Какие есть проблемы у readcommited?