Партицирование данных в S3 (Yandex Object Storage)

В S3 (Yandex Object Storage) можно хранить очень большие объемы данных. При этом запросы к этим данным могут затрагивать не все данные, а только их часть. Если описать правила разметки структуры хранения ваших данных в YDB, тогда данные, которые не нужны для запроса, можно даже не считывать из S3 (Yandex Object Storage). Это значительно ускоряет выполнение запросов без влияния на результат.

Например, данные хранятся в следующей структуре каталогов:

year=2021
    month=01
    month=02
    month=03
year=2022
    month=01

Запрос ниже явно подразумевает, что обработать нужно только данные за февраль 2021-го года и другие данные не нужны.

SELECT
    *
FROM
    objectstorage.'/'
WITH
(
    SCHEMA =
    (
        data String,
        year Int32,
        month Int32
    )
)
WHERE
    year=2021
    AND month=02

Если схема партицирования данных не указана, то из S3 (Yandex Object Storage) будут считаны все хранимые данные, но в результате обработки данные за все другие даты будут отброшены.

Если описать структуру хранения явно, указав, что данные в S3 (Yandex Object Storage) размещены в каталогах по годам и месяцам

SELECT
    *
FROM
    objectstorage.'/'
WITH
(
    SCHEMA =
    (
        data String,
        year Int32,
        month Int32
    ),
    PARTITIONED_BY = "['year', 'month']"
)
WHERE
    year=2021
    AND month=02

то в процессе исполнения запроса из S3 (Yandex Object Storage) будут считаны не все данные, а только данные за февраль 2021-го года, что существенно сократит объем обрабатываемых данных и ускорит обработку, при этом результаты обоих запросов будут идентичны.

Примечание

В примере выше показана работа с данными на уровне соединений. Такой пример выбран только для иллюстративных целей. Мы настоятельно рекомендуем для работы с данными использовать "привязки к данным" и не использовать прямую работу с соединениями.

Синтаксис

При работе на уровне соединений партицирование задается с помощью параметра partitioned_by, где в JSON-формате задается список колонок.

SELECT
    *
FROM
    <connection>.<path>
WITH
(
    SCHEMA=(<field1>, <field2>, <field3>),
    PARTITIONED_BY="['field2', 'field3']"
)

В параметре partitioned_by перечисляются колонки схемы данных, по которым партицированы хранимые в S3 (Yandex Object Storage) данные. Порядок указания полей в параметре partitioned_by определяет вложенность каталогов S3 (Yandex Object Storage) друг в друга.

Например, PARTITIONED_BY=['year', 'month'] определяет структуру каталогов

year=2021
    month=01
    month=02
    month=03
year=2022
    month=01

А partitioned_by=['month', 'year'] определяет другую структуру каталогов

month=01
    year=2021
    year=2022
month=02
    year=2021
month=03
    year=2021

Поддерживаемые типы данных

Партицирование возможно только по следующему набору типов данных YQL:

  • Uint16, Uint32, Uint64
  • Int16, Int32, Int64
  • String, Utf8

При использовании других типов для указания партицирования возвращается ошибка.

Поддерживаемые форматы путей хранения

Формат путей хранения, когда в имени каждого каталога явно указано название колонки, называется "Hive-Metastore форматом" или просто "Hive-форматом".

Такой формат выглядит следующим образом:

month=01
    year=2021
    year=2022
month=02
    year=2021
month=03
    year=2021

Важно

Базовый режим партицирования в YDB поддерживает только Hive-формат.

Для указания произвольных путей хранения необходимо воспользоваться режимом Расширенного партицирования данных.