Parquetテーブルで高速範囲クエリを実行できるようにしたいと思います。返されるデータの量は合計サイズに比べて非常に少ないですが、列全体のスキャンを実行する必要があるため、私のユースケースでは遅すぎます。
インデックスを使用することでこの問題は解決しますが、これはParquet 2.0で追加される予定であると読みました。しかし、私はこれに関する他の情報を見つけることができないので、私はそれがそうではなかったと推測しています。データが並べ替えられた場合、(複数列の)インデックスの追加を妨げる基本的な障害はないと思います。私の場合はそうです。
私の質問は次のとおりです。いつインデックスがParquetに追加されますか。それを行うための高レベルの設計は何ですか?正しいパーティションを指し示すインデックスに既に満足していると思います。
敬具、
シェールド。
Parquetは現在、各データページの最小/最大統計を保持しています。データページは、単一の列の(エンコード後の)1MB以下の値のグループです。複数のページで構成されています Parquetの列チャンク 。
これらの最小/最大値は、列チャンクとチャンクを構成するページの両方をフィルタリングするために使用されます。したがって、フィルターを適用する列でレコードをソートしてから、Parquetにデータを書き込むことで、クエリ時間を改善できるはずです。これにより、統計フィルタリングを最大限に活用できます。
この手法では、ページと行グループのサイズを小さくすることで、より細かいフィルタリングを行うこともできますが、その場合は、エンコードの効率とI/Oの効率を犠牲にします。
2018年12月更新:
Parquet Formatバージョン2.5に列インデックスが追加されました。
https://github.com/Apache/parquet-format/blob/master/CHANGES.md#version-25
その新機能のサブタスクのリストについては、 https://issues.Apache.org/jira/browse/PARQUET-1201 を参照してください。
この機能はParquet形式自体にマージされたばかりで、さまざまなバックエンド(Spark、Hive、Impalaなど)がサポートを開始するまでに時間がかかることに注意してください。
この新機能は列インデックスと呼ばれます。基本的に、Parquetは、Parquetレイアウトに2つの新しい構造、Column IndexとOffset Indexを追加しました。
以下は、それが解決するものと方法のより詳細な技術説明です。
問題ステートメント
現在の形式では、ColumnMetaDataのColumnChunksと、DataPageHeader構造体内の個々のページの統計が格納されます。ページを読み取るとき、統計に基づいてページをスキップできるかどうかを判断するために、リーダーはページヘッダーを処理する必要があります。これは、リーダーが列内のすべてのページにアクセスする必要があるため、ほとんどの列データをディスクから読み取ることを意味します。
目標
最小値と最大値に基づいてページに直接アクセスできるようにすることで、範囲スキャンとポイントルックアップI/Oの両方を効率的にします。特に:
非目標
セカンダリインデックスに相当するもの、つまり、ソートされていないデータに対してキー値でソートされたインデックス構造のサポート。
技術的アプローチ
2つの新しい列ごとの構造を行グループメタデータに追加します。ColumnIndex:これは列の値に基づいて列のページへのナビゲーションを可能にし、スキャン述語OffsetIndexの一致する値を含むデータページを見つけるために使用されます。行インデックス。ColumnIndexを介して一致と識別された行の値を取得するために使用されます。列の行がスキップされると、他の列の対応する行をスキップする必要があります。したがって、RowGroupの各列のOffsetIndexesは一緒に格納されます。
新しいインデックス構造は、フッターの近くのRowGroupとは別に保存されるため、選択的スキャンを実行していない場合、リーダーはそれらを読み取るためのI/Oとデシリアライゼーションのコストを支払う必要がありません。インデックス構造の場所と長さは、ColumnChunkとRowGroupに格納されます。
ClouderaのImpalaチームは、この新しい機能についていくつかのテストを行いました(Apache Impalaコア製品の一部としてはまだ利用できません)。パフォーマンスの向上は次のとおりです。
そして
ご覧のとおり、一部のクエリでは、CPU時間とディスクから読み取る必要のあるデータ量の両方が大幅に改善されました。
2016年からの元の回答:
struct IndexPageHeader {
/** TODO: **/
}
インデックスページヘッダーはまだ実装されていません。
上記のParquet形式のソースコードを参照してください。現在、Parquet 2.0でも表示されません。
しかし、そうです。Parquetに関する上記のRyan Blueからの素晴らしい回答です。これには、疑似インデックス機能(ブルームフィルター)があるということです。
詳細に興味がある場合は、Parquetブルームフィルターと述語プッシュダウンの動作に関する優れたドキュメントをお勧めします https://www.slideshare.net/RyanBlue3/parquet-performance-tuning-the-missing- guide より技術的な実装固有のドキュメント- https://homepages.cwi.nl/~boncz/msc/2018-BoudewijnBraams.pdf