Databricksのテーブルのパーティションをいつ作成すべきか

[When to partition tables on Databricks \| Databricks on AWS](https://docs.databricks.com/tables/partitions.html) [2022/12/21時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

本書では、Databricksのテーブルのパーティションをどのように作成するのか、Delta Lakeのテーブルでパーティショニングをいつ活用すべきかに関して、概要を説明します。ビルトインの機能と最適化によって、1TB以下のデータを持つほとんどのテーブルではパーティションは不要です

Databricksランタイム8.4以降では、DatabricksはデフォルトですべてのテーブルでDelta Lakeを使用します。以下の推奨事項は、すべてのテーブルがDelta Lakeであることを前提としています。

Databricksランタイム11.2以降では、Databricksはパーティションが作成されていないテーブルのデータを自動で取り込み時間に基づいてクラスタリングします。[取り込み時間クラスタリングの活用](#取り込み時間クラスタリングの活用)をご覧ください。

# 小さいテーブルのパーティションを作成する必要はありますか？

1TB以下のデータを持つテーブルのパーティションは作成しないことをお勧めします。

# テーブルにおけるパーティションの最小サイズは何ですか？

すべてのパーティションには、最低1GBのデータが含まれていることをお勧めします。少数かつ大規模なパーティションを持つテーブルは、大量の小規模なパーティションを持つテーブルよりも性能が優れている傾向があります。

# 取り込み時間クラスタリングの活用

Delta LakeとDatabricksランタイム11.2以降とを活用することで、作成する未パーティションのテーブルは、[取り込み時間クラスタリング](https://qiita.com/taka_yayoi/items/d58525efa9e19b7b2fa0)によるメリットを自動で享受することができます。取り込み時間クラスタリングは、データに対する最適化やチューニングの必要なしに、datetimeのフィールドに基づくパーティショニング戦略と同様のクエリーのメリットを提供します。

:::note
**注意**
テーブルに対して`UPDATE`や`MERGE`を用いた大量の変更を実行する際、取り込み時間クラスタリングを維持するには、取り込み順序にマッチするカラムを用いて`ZORDER BY`と`OPTIMIZE`を実行することをお勧めします。例えば、これはイベントのタイムスタンプや作成日を含むカラムとなります。
:::

# Delta Lakeのパーティションは他のデータレイクのパーティションと何が違いますか？

DatabricksやDelta Lakeは、Apache SparkやParquet、Hive、Hadoopのようなオープンソーステクノロジーの上に構築されていますが、これらのテクノロジーで有用なパーティショニングの動機づけと戦略は、一般的にDatabricksで有用とは限りません。テーブルをパーティションする決定をしたのであれば、戦略を選択する前位に以下の事実を検討してください。

- パーティションの境界によってトランザクションは定義されません。Delta Lakeはトランザクションログを通じて[ACID](https://qiita.com/taka_yayoi/items/10f6f1abc6bd8d1f8915)を保証するので、原子性を持つ検索を保証するために、パーティションごとにデータバッチを分割する必要はありません。
- Databricksの計算クラスターは物理的メディアに束縛されたデータ局所性を持ちません。レイクハウスに取り込まれたデータはクラウドオブジェクトストレージに格納されます。データ処理の際、データはローカルディスクストレージにキャッシュされますが、Databricksでは、並列のロードにおいて最低限のデータを特定するためにファイルベースの統計情報を使用します。

# Z-orderとパーティションはどのように動作しますか？

大規模データセットに対するクエリーをスピードアップするために、パーティションとともに[Z-order](https://qiita.com/taka_yayoi/items/3d41a022c0d81b78afaf)インデックスを活用することができます。

:::note
**注意**
Z-orderやパーティションのチューニングを心配する必要がないように、多くのテーブルでは[取り込み時間クラスタリング](#取り込み時間クラスタリングの活用)を活用することができます。
:::

パーティションの境界とZ-orderに基づいたクエリー最適化戦略を計画する際、以下のルールを意識することが重要となります。

- Z-orderは`OPTIMIZE`コマンドと連携して動作します。パーティション教会をまたがるファイルを結合することはできないので、Z-orderクラスタリングはパーティション内でのみ発生します。パーティションが作成されていないテーブルでは、テーブル全体でファイルを結合することが可能です。
- パーティションはカーディナリティの低い、あるいは既知のフィールド(日付のフィールドや物理的位置など)でのみうまく動作しますが、タイムスタンプのようにカーディナリティの高いフィールドではうまく動作しません。Z-orderは、カーディナリティの高いフィールド、無限に成長するフィールド(たとえば、トランザクション、注文テーブルにおけるタイムスタンプや顧客ID)を含むすべてのフィールドで動作します。
- パーティショニングで使用したフィールドにZ-orderを行うことはできません。

# そんなにパーティションが悪いのであれば、なぜいくつかのDatabricksの機能はそれらを活用するのですか？

パーティションは特に非常に大きなテーブルにおいては有効です。パーティショニングに関する数多くのパフォーマンス強化は、非常に大きなテーブル(数百TB以上)にフォーカスしています。

多くのお客様は、ParquetベースのデータレイクからDelta Lakeに移行しています。`CONVERT TO DELTA`文によって、既存のデータを再度書き込むことなしに、ParquetベースのテーブルをDeltaテーブルに変換することができます。このようにして、多くのお客様は以前のパーティション戦略を継承する大規模なテーブルを手にすることができます。Databricksによって開発されるいくつかの最適化処理は、可能な限りこれらのパーティションを活用しようとし、Delta Lake向けに最適化されていないパーティション戦略のいくかの副作用を軽減します。

Delta LakeとApache Sparkはオープンソーステクノロジーです。Databricksでは、パーティションへの依存度を削減する機能の導入を進めますが、オープンソースコミュニティでは、複雑性を増加させるような新機能を構築し続けるかもしれません。

# カスタムのパーティショニングを用いてDatabricksのビルトインの最適化処理を上回ることは可能ですか？

Apache SparkやDelta Lakeの経験が豊富である何人かのユーザーは、[取り込み時間クラスタリング](#取り込み時間クラスタリングの活用)よりも優れたパフォーマンスを提供するパターンを設計、実装することができるかもしれません。まずいパーティショニング戦略の実装は、後段におけるパフォーマンスに対する非常にネガティブな反動を引き起こす可能性があり、修正するためにはデータの完全な再書き込みが必要になるかもしれません。コストのかかる非効率性を招くことがないように、多くのユーザーにはデフォルト設定を使用することをお勧めします。

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)