Snowpark Python: Beseitigen Sie wiederholte Unterabfragen in von Snowpark generierten Abfragen ¶
Achtung
Diese Verhaltensänderung ist in Bundle 2025_04 enthalten.
Den aktuellen Status des Bundles finden Sie unter Bundle-Verlauf.
Durch die wiederholte Löschung von Unterabfragen werden identische Sub-DataFrames innerhalb eines Abfrageplans identifiziert und allgemeine Tabellenausdrücke (Common Table Expressions, CTEs) verwendet, um die endgültige Abfrage zu erstellen. Fast die Hälfte der Abfragen mit Kompilierungszeiten von mehr als einer Sekunde enthält mindestens eine redundante Unterabfrage. Der Vorteil dieser Optimierung hängt von der Menge und Komplexität der identifizierten doppelten Unterabfragen ab.
Diagnoseschritte:
SQL-Kompilierungsfehler für eine Snowpark-Datenpipeline, die zuvor fehlerfrei ausgeführt wurde.
Aufgrund von Fehlern in der SQL-Generierung werden falsche Ergebnisse generiert.
Eindämmung:
Ein Downgrade auf eine ältere Version des Snowpark-Clients kann das Problem eindämmen.
Durch das Zurücksetzen des Parameters
PYTHON_SNOWPARK_USE_CTE_OPTIMIZATION_VERSION
wird das Problem eingedämmt.Um von dieser Änderung nicht betroffen zu sein, sollten Sie Snowpark-basierte Workflows an eine Snowpark Python-Version angeheftet halten, die niedriger als 1.31.1 ist. Wenn Sie zum Beispiel eine gespeicherte Python-Prozedur verwenden, legen Sie
PACKAGES=('snowflake-snowpark-python==1.30.0')
beim Erstellen der gespeicherten Prozedur fest. Im Falle eines Snowflake-Notebooks oder Python-Arbeitsblatts wechseln Sie zu einer Snowpark Python-Version, die niedriger als 1.31.1 ist.
Um den Unterschied zwischen altem und neuem Verhalten zu veranschaulichen, betrachten Sie die folgenden DataFrame-Transformationen in Snowpark Python:
df = session.table("test_table")
df1 = df.with_column("a", F.col("A") + 1).filter(df.a > 1)
df1 = df1.union_all(df1)
print(df1.queries["queries"][0])
- Vor der Änderung:
Weil die
union_all
oben dasselbe DataFramedf1
zweimal verwendet, wiederholen die generierten SQL-Abfragen die zugrunde liegende Unterabfrage zweimal:( SELECT * FROM ( SELECT "B", "C", ( "A" + 1 ) AS "A" FROM test_table ) WHERE ( "A" > 1 ) ) UNION ALL ( SELECT * FROM ( SELECT "B", "C", ( "A" + 1 ) AS "A" FROM test_table ) WHERE ( "A" > 1 ) )
- Nach der Änderung:
Die Optimierung wird erkennen, dass
df1
zweimal verwendet wird, die Unterabfrage durch einen CTE-Ausdruck ersetzen und diesen dann zum Erstellen der Abfrage verwenden:WITH SNOWPARK_TEMP_CTE_7G3ZFVJYBK AS ( SELECT * FROM ( SELECT "B", "C", ( "A" + 1 ) AS "A" FROM test_table ) WHERE ( "A" > 1 ) ) ( SELECT * FROM ( SNOWPARK_TEMP_CTE_7G3ZFVJYBK ) ) UNION ALL ( SELECT * FROM ( SNOWPARK_TEMP_CTE_7G3ZFVJYBK ) )
Ref: 1995