注: 以下の翻訳の正確性は検証されていません。AIPを利用して英語版の原文から機械的に翻訳されたものです。
データセットのプロジェクションは、多くのクエリのパフォーマンスを向上させることができます。複数のクエリパターン(たとえば、2つの別々の列でフィルター処理する)で最適化したいデータセットがある場合、データセットにプロジェクションを追加することを検討してください。プロジェクションの具体的な使用例は以下に記載されています。
各プロジェクションは通常、特定のクエリパターンをサポートし、列のセットに対するフィルター処理や結合を改善することに焦点を当てています。複数のプロジェクションをデータセットに追加することができ、すべての列タイプがプロジェクションでサポートされています。さらに、プロジェクションはスナップショットまたはインクリメンタルにビルドされたデータセットの両方に追加できます。Noho サービスはプロジェクションを管理するために使用され、プロジェクションを設定する際にデータセットのスキーマにリファレンスされます。
プロジェクションにはいくつかの制限があります:
以下の使用例を確認して、プロジェクションがユーザーの使用例に適しているかどうかを判断してください。プロジェクションを設定する方法を学び、始めましょう。
多くの種類のクエリはプロジェクションから利益を得ます。以下の例は次の内容を示します:
順序付けされた列のリストを指定して、リストのプレフィックスに対するフィルター処理を最適化します。プロジェクションは、列を定数値と比較するフィルター処理のみを高速化します。また、文字列の列に対するフィルター処理は大文字と小文字を区別する必要があります。
たとえば、列の順序付けされたリスト ["x", "y", "z"]
に対するフィルター処理を最適化するプロジェクションがあるとします。
次のタイプのクエリを高速化します:
SELECT * FROM dataset WHERE x = 5 AND y = 10 AND z = '15'
SELECT * FROM dataset WHERE x = 5 AND y = 10
SELECT * FROM dataset WHERE x = 5 AND q = 3
q = 3
)、Sparkはフィルター条件を自動的にデータソースに「プッシュ」しようとし(この場合 x = 5
)、他の条件を後で適用します。しかし、次のタイプのクエリは最適化されません:
SELECT * FROM dataset WHERE abs(x) == 10
abs(x) == 10
は列を定数値と比較していません。SELECT * FROM dataset WHERE x % 100 == 10
x % 100 == 10
は列を定数値と比較していません。SELECT * FROM dataset WHERE y = 10
["y"]
は ["x", "y", "z"]
のプレフィックスではありません。SELECT * FROM dataset WHERE z = '15'
["z"]
は ["x", "y", "z"]
のプレフィックスではありません。SELECT * FROM dataset WHERE x = 5 OR q = 3
x = 5
のフィルターを「プッシュ」できません。なぜなら、x = 5
がfalseで q = 3
がtrueである行を見逃す可能性があるからです。プロジェクションはフィルター処理する列に対する範囲クエリを高速化することもできます。たとえば:
SELECT * FROM dataset WHERE x > 5 AND x < 10
SELECT * FROM dataset WHERE s LIKE 'SOME_PREFIX%'
順序のない列のセットとバケット数を指定して、その正確なセットとバケット数でのみ結合を最適化します。
たとえば、{"x", "y"}
での結合を最適化するプロジェクションは、次のタイプのクエリを最適化します:
SELECT * FROM dataset1 INNER JOIN dataset2 ON dataset1.x = dataset2.x AND dataset1.y = dataset2.y
しかし、次のクエリは最適化されません:
SELECT * FROM dataset1 INNER JOIN dataset2 ON dataset1.x = dataset2.x
Foundryでは、大規模なデータセットの結合は通常、ソートマージ結合を行います。これは、各データセットを結合キーに従ってパーティショニングし、各パーティションをそのキーでソートし、同じキーを持つ(ソートされた)パーティションをマージすることを含みます。
Foundryのほとんどのプロジェクションコンシューマは、ソートマージ結合を行う際にプロジェクションが既にソートされている事実をデフォルトで活用しません。そのため、Sparkクエリプランにソートが表示されることがあります。トランスフォームでは、Sparkプロファイル BUCKET_SORTED_SCAN_ENABLED
を使用して、プロジェクションがソートされていることに基づいてSparkの動作を変更できますが、これが常にパフォーマンスを向上させるわけではなく、実際にパフォーマンスを悪化させることもあります。
Foundryでは、集計は通常、データセットを集計キーに従ってパーティショニングするシャッフル交換を行います。ハッシュバケットされたプロジェクション(これはすべての結合最適化プロジェクションに当てはまりますが、フィルター処理最適化プロジェクションには当てはまらない場合があります)から読み取る場合、コンシューマはこのシャッフルを回避でき、集計中のパフォーマンス向上が得られます。主キー期待値チェック がインクリメンタルに更新される追加のみのデータセットでは、プロジェクション(主キー列に対する)が特に有益です。プロジェクションによって実行される圧縮と、プロジェクションのハッシュバケット化が期待値を計算するために使用される集計で活用されるためです。
インクリメンタルパイプラインは非常に高いファイル数をもたらし、それに伴い読み取りパフォーマンスが低下します。たとえば、5分ごとに10個のパーティションを書き込むパイプラインは、1年間で100万個以上のファイルを書き込みます。これらは、入力パーティションのリストを生成することなど、多くの理由で読み取りが困難です。
プロジェクションは、このようなインクリメンタルパイプラインを透過的に圧縮する方法を提供します。フィルター処理または結合に最適化されたプロジェクションを設定するだけで、読み取りはプロジェクションを使用します。インクリメンタルパイプラインにプロジェクションを使用する方法について詳しく学んでください。
プロジェクションが最新のデータセットと完全に一致していない場合でも、フィルター処理や結合の最適化の利点を活用できます。最新のトランザクション時点でプロジェクションが最後にビルドされた時と、現在の最新のトランザクション時点の間に、SNAPSHOT、DELETEトランザクション(または既存のファイルを変更するUPDATEトランザクション)がデータセットに対して行われていなければ問題ありません。
CSVはデータクエリには非効率的なファイル形式ですが、Foundryにアップロードされたデータ(Data Connection経由でファイルシステムソースから、手動アップロードなど)は、最初にCSV形式であることが一般的です。これらのCSVをParquetなどのより効率的な形式に変換する1つの方法は、トランスフォームジョブを作成することです。または、プロジェクションを追加することもできます。読み取り操作は最適化されたプロジェクションを使用してパフォーマンスを向上させる一方で、データセットには元のCSVファイルが含まれたままです。