概要
presto等のクエリの速度・負荷の改善に当たって、parquetへの理解が必要だったので、ポイントをまとめたい。
参考
- The Parquet Format and Performance Optimization Opportunities Boudewijn Braams (Databricks)
- https://github.com/apache/parquet-format/blob/master/Encodings.md
- Amazon Athena のパフォーマンスチューニング Tips トップ 10
観点
Encodingへの意識
parquetの用いるEncodingの手法(Dictionary EncodingやDelta Encoding)などを意識して、parquetファイルを作りたい。
Encodingを効率的に行うことでデータの圧縮が効率的にできる。これはpre-sortやDictionary sizeやrow groupの長さなどの調整などによりできる。
parquetの持つ統計情報を有益なものにする
parquetは統計情報としてデータのまとまり(row group, column chunk, page)でmin/max/countなどを持っている。この統計情報を有益なものにするためにはpre sortが必要になることがある。
ファイルサイズを最適化する
よくあるのはpartitionしすぎて、小さいファイルが大量にあるケース。parquetファイルを読むときはクエリーエンジンは内部のデータ構造を初期化したり、統計情報をparseしたりと様々な処理を行う。それが多すぎるとperformanceの劣化に繋がる。逆に大きなファイルが1個あると、これはこれでperformanceは劣化する。いずれもrepartitioning(もしくはそれに相当する処理)が必要だが、repartitioning自体様々な困難(関係者に通達、適切な粒度を見つけることの難しさ、バックアップを一々取らなければならないetc)があるので、repartitioningをしてくれるopen sourceやツールを使った方が良いだろう。
圧縮アルゴリズム
parquetではデフォルトではsnappyという圧縮アルゴリズムが使われている。基本的にはsnappyで構わないと思うが、問題があった場合他の圧縮アルゴリズムを使うことを検討すれば良い。