注: 以下の翻訳の正確性は検証されていません。AIPを利用して英語版の原文から機械的に翻訳されたものです。
ROW_NUMBER
、FIRST
、LAST
、LEAD
、LAG
、NTILE
、ARRAY_AGG
、ARRAY_AGG_DISTINCT
をウィンドウ関数で使用する場合、非決定性に注意してください。列 A でパーティションを作成し、列 B で並べ替えると想像してみてください。列 A の同じ値に対して、列 B の同じ値を持つ複数の行がある場合、これらのウィンドウ関数の結果は非決定的になる可能性があります。つまり、同じ入力データとロジックが与えられた場合に異なる結果が得られることがあります。
これらの式を式ボードで使用する場合、ウィンドウ関数の ORDER BY
句が決定的であることを確認するために、警告が表示されます。
データを使用した例を見てみましょう。
name | class | grade |
---|---|---|
Aaron | Math | 95 |
Burt | Math | 95 |
Chrissy | Math | 80 |
Angelica | Science | 77 |
Burt | Science | 81 |
Charlie | Science | 66 |
各クラスで成績順に学生をランク付けしたいので、新しい行「rank」を式 ROW_NUMBER() OVER (PARTITION BY "class" ORDER BY "grade" DESC)
で追加します。
この結果を得ます。
name | class | grade | rank |
---|---|---|---|
Aaron | Math | 95 | 1 |
Burt | Math | 95 | 2 |
Chrissy | Math | 80 | 3 |
Angelica | Science | 77 | 2 |
Burt | Science | 81 | 1 |
Charlie | Science | 66 | 3 |
しかし、時々この結果が得られます。
name | class | grade | rank |
---|---|---|---|
Aaron | Math | 95 | 2 |
Burt | Math | 95 | 1 |
Chrissy | Math | 80 | 3 |
Angelica | Science | 77 | 2 |
Burt | Science | 81 | 1 |
Charlie | Science | 66 | 3 |
Aaron と Burt が数学で同じ成績を持っているため、「rank」行は非決定的です。行を決定的にするために、式に "name" 列を追加して、ROW_NUMBER() OVER (PARTITION BY "class" ORDER BY "grade" DESC, "name" ASC)
を使用します。この式では、同じ成績を持つ行を「name」列で決定するため、以下の結果が常に得られます。
name | class | grade | rank |
---|---|---|---|
Aaron | Math | 95 | 1 |
Burt | Math | 95 | 2 |
Chrissy | Math | 80 | 3 |
Angelica | Science | 77 | 2 |
Burt | Science | 81 | 1 |
Charlie | Science | 66 | 3 |
上記のウィンドウ関数以外にも、CURRENT_DATE
、CURRENT_TIMESTAMP
、CURRENT_UNIX_TIMESTAMP
、MONOTONICALLY_INCREASING_ID
は非決定的です。
CURRENT_DATE
、CURRENT_TIMESTAMP
、CURRENT_UNIX_TIMESTAMP
の場合、これらの値はパスの更新時にのみ計算されます。たとえば、1 日目に CURRENT_DATE
を使用して新しい列を作成し、2 日目に解析に戻ると、新しい列は前日の日付を反映したままになります。
Spark 計算の分散性のため、算術演算でのオペランドの順序は非決定的です(つまり、1+2 と 2+1 のような場合)。この非決定的な順序は、入力タイプが double
の場合、非決定的な出力を作成する集約につながります。これは、同じ入力を持つにもかかわらず、double に対する集約が 1 つの計算と別の計算で異なることがあることを意味します。これらの違いは非常に小さく、たとえば 0.000001 です。
たとえば、double 列の mean
や variance
を取ると、非決定的な列ができます。非決定的な列でアクションを実行する結果(たとえば、フィルタリング)も非決定的になります。
解析で double 列の mean
、sum
、stddev
、variance
、corr
、sum_distinct
を取ると、非決定的な列が作成されます。
例を見てみましょう。
例えば、double 列 pickup_latitude
を持っているとします。ピボットテーブルでは、double 列 pickup_latitude
の平均を取っています。ピボットされたデータに切り替えると、非決定的な列が作成されます。
新しく作成された列でフィルタリングを行うと、このフィルタの結果は非決定的になります。例えば、上のスクリーンショットでは、スタテンアイランドの平均 pickup_latitude
は 40.5830495 です。その値でフィルタリングすると、1 行が残ります。
しかし、このパスを再計算すると、フィルターの後に行が表示されなくなる可能性があります。これは、平均値がわずかに変化したためです。非決定的な列に対して正確なフィルターを使用することを避けることをお勧めします(たとえば、平均 = 40.5830495 にフィルタリング)。また、非決定的な列を結合キーとして使用することも避けてください。
Contour で非決定的な列でアクションを実行する場合(たとえば、その列でフィルタリングする場合)、そのアクションが実行されるボードに警告が表示されます。警告には、非決定的な列の源となる集約が記載されています。
解析が非決定的である兆候の 1 つは、一貫性のない行数です。たとえば、Summary ボードを挿入し、行数を変更しない一連の変換を実行し、別の Summary ボードを追加した解析があるとします。2 つの Summary ボードの行数が一致しない場合、上のパスに非決定的な操作がないか調べる必要があります。非決定的な関数を使用している場合や、double の集約を使用している場合の UI の警告表示に注意してください。