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])
Copy
Vor der Änderung:

Weil die union_all oben dasselbe DataFrame df1 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 ) )
Copy
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 ) )
Copy

Ref: 1995