मैं खुद एक टेबल से जुड़ने पर स्पार्क के व्यवहार का पता लगा रहा हूं। मैं डेटाब्रिक्स का उपयोग कर रहा हूं।
मेरा डमी परिदृश्य है:
डेटाफ़्रेम ए के रूप में एक बाहरी तालिका पढ़ें (अंतर्निहित फाइलें डेल्टा प्रारूप में हैं)
डेटाफ्रेम ए के रूप में डेटाफ्रेम बी को केवल कुछ निश्चित कॉलम के साथ परिभाषित करें
कॉलम 1 और कॉलम 2 पर डेटाफ्रेम ए और बी को मिलाएं
(हां, इसका कोई मतलब नहीं है, मैं स्पार्क के अंतर्निहित यांत्रिकी को समझने के लिए प्रयोग कर रहा हूं)
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)। मैं तो repartition और कैश करने की कोशिश की (प्रयास 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()
उत्पन्न संबंधित डैग संलग्न हैं।
मेरे प्रश्न हैं:
प्रयास में क्यों 1 तालिका को कैश किया गया प्रतीत होता है भले ही कैशिंग स्पष्ट रूप से निर्दिष्ट नहीं किया गया है।
InMemoreTableScan को हमेशा इस प्रकार के दूसरे नोड द्वारा अनुसरण क्यों किया जाता है।
प्रयास में 3 कैशिंग दो चरणों में क्यों प्रतीत होते हैं?
प्रयास में 3 WholeStageCodegen एक (और केवल एक) InMemoreTableScan का अनुसरण करता है।