Pages
Column Chunk состоит из страниц
Column chunk — это не монолитный блок. Внутри он разбит на страницы (pages) — минимальную единицу кодирования и компрессии. Каждая страница содержит подмножество значений колонки и может быть декомпрессирована независимо.
Три типа страниц:
- Dictionary Page — словарь уникальных значений (не более одной на column chunk)
- Data Page — закодированные значения (основной тип, их может быть много)
- Index Page — зарезервирован в спецификации, на практике не используется
Column Chunk: department (BYTE_ARRAY)
Page Header (тип, размеры, num_values)
Page Header (Thrift): тип страницы, размер до/после компрессии, количество значений. Всегда идёт первым перед данными страницы.Data Page v1 vs v2
Parquet определяет две версии data page с принципиально разным подходом к компрессии.
Data Page v1 (DATA_PAGE)
Repetition levels, definition levels и закодированные значения сжимаются вместе как единый блок:
[Page Header]
[Compressed Block:
repetition levels
<Icon name="check" className="text-emerald-400" size="1.2em" /> definition levels
<Icon name="check" className="text-emerald-400" size="1.2em" /> encoded values
]
Чтобы прочитать только levels (для пропуска страницы) — нужно декомпрессировать всю страницу.
Data Page v2 (DATA_PAGE_V2)
Levels хранятся отдельно от значений и не сжимаются. Компрессия применяется только к encoded values:
[Page Header (с длинами levels)]
[Repetition Levels — uncompressed]
[Definition Levels — uncompressed]
[Encoded Values — compressed]
v1: всё сжато вместе
Page Header
Thrift-сериализованный заголовок. Содержит uncompressed_page_size, compressed_page_size, num_values, encoding.Нельзя прочитать levels без декомпрессии
v2: levels отдельно
Page Header v2
Расширенный заголовок: добавлены repetition_levels_byte_length и definition_levels_byte_length — точные размеры секций.Levels доступны без декомпрессии
Data Page v2 особенно полезен для вложенных данных (nested structures), где repetition/definition levels критичны для навигации. Для плоских таблиц без NULL разница минимальна — levels занимают 0 байт.
Dictionary Page
Dictionary Page содержит упорядоченный список уникальных значений колонки. Data pages при dictionary encoding хранят только целочисленные индексы в этот словарь.
Правила:
- Максимум одна dictionary page на column chunk
- Если есть — всегда первая страница в chunk
- Fallback: если словарь превышает
dictionary_page_size_limit(обычно 1 MB) — writer переключается на PLAIN encoding
С Dictionary
Без Dictionary (PLAIN)
Dictionary encoding даёт 20x+ сжатие для колонок с низкой кардинальностью (status, country, category). Для колонок с высокой кардинальностью (UUID, timestamp) словарь бесполезен — writer автоматически переключается на PLAIN.
Page Header
Каждая страница начинается с Thrift-сериализованного заголовка. Формат зависит от типа страницы:
| Поле | Data Page v1 | Data Page v2 | Dictionary Page |
|---|---|---|---|
type | DATA_PAGE | DATA_PAGE_V2 | DICTIONARY_PAGE |
uncompressed_page_size | |||
compressed_page_size | |||
num_values | |||
encoding | |||
definition_levels_byte_length | — | — | |
repetition_levels_byte_length | — | — | |
is_compressed | — | — | |
statistics | (legacy) | (legacy) | — |
Поле statistics в page header считается legacy. Современные ридеры используют ColumnIndex и OffsetIndex из File Metadata для page-level statistics — они эффективнее, потому что не требуют чтения заголовков каждой страницы.
Размер страницы: trade-offs
Размер data page настраивается параметром data_page_size (дефолт 1 MB в большинстве writers):
| Маленькая страница (64 KB) | Стандартная (1 MB) | Большая страница (8 MB) |
|---|---|---|
| Точный page-level skipping | Хороший баланс | Лучшая компрессия |
| Больше page headers | Дефолт везде | Грубый skipping |
| Хуже компрессия | Достаточная точность | Больше памяти на декодирование |
Маленькие страницы улучшают page-level predicate pushdown (ColumnIndex/OffsetIndex). Но если данные не отсортированы — page skipping всё равно неэффективен, и мелкие страницы лишь увеличивают overhead.
Ключевые выводы
- Page — минимальная единица кодирования и компрессии внутри column chunk
- Dictionary Page (максимум одна) хранит словарь уникальных значений; data pages ссылаются на него индексами
- Data Page v1 — levels + values сжаты вместе; v2 — levels отдельно (доступны без декомпрессии)
- Page Header (Thrift) содержит тип, размеры, encoding, количество значений
- data_page_size (дефолт 1 MB) контролирует гранулярность: мелкие страницы → точнее skipping, крупнее → лучше компрессия