テーブルをそれ自体に結合するときのSparkの動作を調査しています。Databricksを使用しています。
私のダミーのシナリオは:
外部テーブルをデータフレームAとして読み取ります(基礎となるファイルはデルタ形式です)
特定の列のみが選択されたデータフレームBをデータフレームAとして定義する
column1とcolumn2のデータフレームAとBを結合する
(はい、あまり意味がありません。Sparkの基礎となるメカニズムを理解するために実験しているだけです)
a = spark.read.table("table") \
.select("column1", "column2", "column3", "column4") \
.withColumn("columnA", lower((concat(col("column4"), lit("_"), col("column5")))))
b = a.select("column1", "column2", "columnA")
c= a.join(b, how="left", on = ["column1", "column2"])
私の最初の試みは、コードをそのまま実行することでした(試行1)。次に、パーティションの分割とキャッシュを試みました(2回試行)。
a = spark.read.table("table") \
.select("column1", "column2", "column3", "column4") \
.withColumn("columnA", lower((concat(col("column4"), lit("_"), col("column5")))))
.repartition(col("column1"), col("column2")).cache()
最後に、パーティションを分割し、並べ替え、キャッシュしました
a = spark.read.table("table") \
.select("column1", "column2", "column3", "column4") \
.withColumn("columnA", lower((concat(col("column4"), lit("_"), col("column5")))))
.repartition(col("column1"), col("column2")).sortWithinPartitions(col("column1"), col("column2")).cache()
生成されたそれぞれのDAGは添付のとおりです。
私の質問は:
キャッシングが明示的に指定されていないにもかかわらず、試行1でテーブルがキャッシュされているように見える理由。
InMemoreTableScanの後に常にこのタイプの別のノードが続く理由。
なぜ3キャッシングが2段階で行われるように見えるのですか?
なぜ試行3の場合、WholeStageCodegenは1つ(そして1つだけ)のInMemoreTableScanに従います。