行グループ内の列チャンクとページ、辞書ページの関係を示すParquet構造の概念図

Apache Parquetは、データを列チャンクとページに分けて格納する列指向ファイル形式です。この構造によって、必要な列だけを読む処理や、繰り返し値を別の形で表すエンコーディングが可能になります。ただし、Parquetを選べばどのクエリも速くなるわけではありません。実際に読むデータ量は、フッターのメタデータ、選択列、行グループの大きさ、エンコーディング、圧縮方式、writerとreaderの実装に左右されます。

フッターメタデータが読み取り位置を示す

Parquetファイルではデータ領域の後ろにファイルメタデータが置かれ、続いてメタデータ長と末尾のマジックナンバーが記録されます。メタデータには行グループと各列チャンクの位置が含まれるため、readerは先に情報を読み、必要なチャンクを探せます。ファイルを理解するときは、値のバイト列だけでなく、フッターと位置情報も確認する必要があります。

行グループは行をまとめる論理的な区画です。各行グループには列ごとのチャンクがあり、チャンクはさらにページに分かれます。ページはエンコーディングや圧縮の情報が適用される単位です。つまり「列指向」は値が列ごとにまとまることを指し、行グループは同じ行範囲の複数列をまとめます。ファイル、行グループ、チャンク、ページの境界は関連しますが、同じ意味ではありません。

クエリが一部の列しか求めない場合、構造上は不要な列チャンクを要求せずに済む可能性があります。しかし、これは形式が提供する機能であり、すべての実行エンジンが常に無関係な読み取りを省けるという保証ではありません。メタデータ、クエリ計画、readerの対応状況を確認してください。拡張子だけから実際のI/Oを推測せず、計画と読み取りバイト数を調べます。

辞書エンコーディングは値をインデックスに置き換える

列チャンクは一部または全体を辞書エンコードできます。その場合、実際の値を辞書ページに保存し、データページには値を指すインデックスを記録します。同じラベルや文字列が何度も出る列では、長い値を各行に繰り返す代わりに辞書とインデックスを使えます。インデックス列にはランレングスやビットパッキングのハイブリッド表現が使われ、同じ値の繰り返しや小さな番号を効率よく表せる場合があります。

一方、辞書にも記録コストがあります。値の種類が多くほとんど重複しない列や、辞書が大きくなり続ける列では、辞書とインデックスの両方を保存する利点が小さくなります。実装によっては辞書が大きくなった段階で辞書方式をやめ、通常の値表現へ切り替えます。その切り替え条件はデータやwriterの実装に依存し、形式だけから一律には決まりません。辞書が使われたという情報だけで、ファイルが小さい・読み取りが速いと結論づけないでください。

エンコーディングと圧縮も別の段階です。エンコーディングは値の表し方を決め、圧縮コーデックはページのデータをさらに処理します。繰り返し値は辞書、コーデック、または両方の恩恵を受けることがありますが、値の分布や実装によって結果は異なります。比較時には個別の設定として記録し、どの段階が変化を生んだかを切り分けます。

ページと圧縮方式の役割を分ける

データページには値のデータが入り、ネストした列や省略可能な列では反復レベル・定義レベルも含まれることがあります。ページヘッダーはデータの読み方や圧縮の有無をreaderに伝えます。ページ単位の構造は、条件やメタデータが対応していれば不要なページを避ける余地を作ります。

ただし、ページを常に読み飛ばせるわけではありません。エンジンによってページインデックス、統計情報、エンコーディングの利用方法が異なり、フィルターが想定より多くのデータを読むこともあります。また、圧縮コーデックを変えただけで辞書方式まで変わるとは限りません。調査ではエンコーディング、コーデック、統計、実際の読み取り量を分けて記録し、物理配置とクエリ動作を結び付けます。

専門家の視点:形式が可能にすることとreaderの実動作を区別する

Apache Parquetのドキュメントは、メタデータで列チャンクの位置を示し、readerが必要なチャンクを選べる構造を説明します。形式仕様は行グループ、チャンク、ページ、辞書値とインデックスの配置を定義します。これらはファイルの構造を示す根拠ですが、特定エンジンがどれだけ読み飛ばすか、処理が何倍速くなるかまでは保証しません。仕様から検証可能な予想を立て、実際のwriter・readerのバージョン、クエリ計画、読み取りバイト数で確かめるのが実務的です。

再現できる負荷で性能を測る

少数の列を読む分析では、ファイルとreaderが列を選択的に読み取れるとき、列チャンクの配置が役立つ可能性があります。大きな行グループは連続読み取りや並列処理に向く場合がある一方、小さなグループは境界やメタデータを増やすことがあります。どちらがよいかは処理負荷、保存先、実行エンジンによって変わります。圧縮も保存・転送量とCPU処理のトレードオフを作るため、ファイルサイズだけでは性能を評価できません。

比較ではデータ、スキーマ、クエリ、readerを固定し、writer設定を一つずつ変えます。writerのライブラリとバージョン、行グループ設定、辞書・圧縮設定、出力サイズ、読み取りバイト数、実行時間、結果の正しさを記録します。代表的な複数クエリを測れば、列選択、行グループ、辞書、コーデック、reader実装のどこから差が生じたか判断しやすくなります。

Parquetは列指向データを扱うための柔軟な基盤であり、自動チューニングの規則ではありません。メタデータとページ構造はいくつかの最適化を可能にしますが、信頼できる結論は実際のwriter・reader・負荷を組み合わせて測った結果から得られます。形式仕様はその測定を始めるための地図であり、測定の代わりにはなりません。

出典