Есть ли разница при вложенном (многоуровневом) партиционировании таблицы?

«Есть ли разница при вложенном (многоуровневом) партиционировании таблицы?» — вопрос из категории SQL и базы данных, который задают на 33% собеседований Data Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, разница существенна, и порядок уровней вложенного партиционирования критически важен для производительности и управления данными.

Влияние порядка партиций: Предположим, таблица партиционирована по date (день) и затем по region.

-- Hive/Spark SQL пример
CREATE TABLE sales (
    id INT,
    amount DECIMAL
) PARTITIONED BY (sale_date DATE, region STRING);

Физически данные будут организованы в каталогах: /sale_date=2023-10-01/region=EMEA/..., /sale_date=2023-10-01/region=NA/....

  1. Производительность запросов (Partition Pruning):

    • Запрос с фильтром только по sale_date будет эффективным: система прочитает только каталоги за нужную дату.
    • Запрос с фильтром только по region будет неэффективным (full scan): системе придется заглядывать во все каталоги sale_date=*, чтобы найти подкаталоги с нужным регионом.
  2. Управление данными:

    • Удаление старых данных (ALTER TABLE ... DROP PARTITION (sale_date='2023-01-01')) выполняется быстро и атомарно для всей даты.
    • Удаление данных по региону для всех дат потребует множества операций.

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

Пример в PostgreSQL (декларативное партиционирование):

CREATE TABLE sales (
    id SERIAL,
    sale_date DATE NOT NULL,
    region TEXT NOT NULL,
    amount DECIMAL
) PARTITION BY RANGE (sale_date);

-- Создание партиций по дате
CREATE TABLE sales_2023_q1 PARTITION OF sales
    FOR VALUES FROM ('2023-01-01') TO ('2023-04-01');

-- Затем внутри можно создать субпартиционирование по region
-- (в PostgreSQL это реализуется созданием своих партиционированных таблиц для sales_2023_q1).