Estoy explorando el comportamiento de Spark al unir una tabla consigo misma. Estoy usando Databricks.
Mi escenario ficticio es:
Leer una tabla externa como marco de datos A (los archivos subyacentes están en formato delta)
Defina el marco de datos B como el marco de datos A con solo ciertas columnas seleccionadas
Unir los marcos de datos A y B en la columna 1 y la columna 2
(Sí, no tiene mucho sentido, solo estoy experimentando para entender la mecánica subyacente de 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"])
Mi primer intento fue ejecutar el código tal como está (intento 1). Luego intenté repartir y almacenar en caché (intento 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()
Finalmente, particioné, clasifiqué y almacené en caché
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()
Los dags respectivos generados están como adjuntos.
Mis preguntas son:
¿Por qué en el intento 1 la tabla parece estar en caché aunque el almacenamiento en caché no se haya especificado explícitamente?
Por qué InMemoreTableScan siempre es seguido por otro nodo de este tipo.
¿Por qué en el intento 3 el almacenamiento en caché parece tener lugar en dos etapas?
Por qué en el intento 3 WholeStageCodegen sigue a uno (y solo uno) InMemoreTableScan.