Sto esplorando il comportamento di Spark quando mi unisco a un tavolo. Sto usando Databricks.
Il mio scenario fittizio è:
Leggi una tabella esterna come dataframe A (i file sottostanti sono in formato delta)
Definire il frame di dati B come frame di dati A con solo determinate colonne selezionate
Unisci i frame di dati A e B su colonna1 e colonna2
(Sì, non ha molto senso, sto solo sperimentando per capire la meccanica di base di 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"])
Il mio primo tentativo è stato quello di eseguire il codice così com'è (tentativo 1). Ho quindi provato a ripartizionare e memorizzare nella cache (tentativo 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()
Alla fine, ho ripartizionato, ordinato e memorizzato nella 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()
I rispettivi punti generati sono come allegati.
Le mie domande sono:
Perché nel tentativo 1 la tabella sembra essere memorizzata nella cache anche se la memorizzazione nella cache non è stata specificata in modo esplicito.
Perché InMemoreTableScan è sempre seguito da un altro nodo di questo tipo.
Perché nel tentativo 3 la memorizzazione nella cache sembra avvenire su due livelli?
Perché nel tentativo 3 WholeStageCodegen segue uno (e solo uno) InMemoreTableScan.