Snowpark Python : Éliminer les sous-requêtes répétées dans les requêtes générées par Snowpark

Attention

Ce changement de comportement fait partie du bundle 2025_04.

Pour connaître le statut actuel du bundle, reportez-vous à Historique du bundle.

L’élimination répétée des sous-requêtes identifie des sous-DataFrames identiques dans un plan de requête et utilise des expressions de table communes (CTEs) pour créer la requête finale. Près de la moitié des requêtes dont les temps de compilation dépassent une seconde contiennent au moins une sous-requête redondante. L’avantage de cette optimisation s’étend à la quantité et à la complexité des sous-requêtes en double identifiées.

  • Étapes de diagnostic :

    • Erreur de compilation SQL sur un pipeline de données Snowpark qui fonctionnait sans erreur auparavant.

    • Résultats incorrects générés à cause des bogues dans la génération SQL.

  • Atténuation :

    • Le passage à une ancienne version du client Snowpark atténue le problème.

    • La désactivation du paramètre PYTHON_SNOWPARK_USE_CTE_OPTIMIZATION_VERSION atténue le problème.

      Pour ne pas être affecté par ce changement, gardez les workflows basés sur Snowpark épinglés dans une version de Snowpark Python qui est inférieure à 1.31.1. Par exemple, si vous utilisez une procédure stockée Python, définissez PACKAGES=('snowflake-snowpark-python==1.30.0') lors de la création de la procédure stockée. Dans le cas d’un Notebook Snowflake ou d’une feuille de calcul Python, passez à une version Snowpark Python inférieure à 1.31.1.

Pour démontrer la différence entre l’ancien et le nouveau comportement, considérez les transformations DataFrame suivantes dans 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
Avant la modification:

Parce que le union_all ci-dessus utilise le même DataFrame df1 deux fois, les requêtes SQL générées répéteront la sous-requête sous-jacente deux fois :

( 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
Après la modification:

L’optimisation détectera que le df1 est utilisé deux fois, remplacera la sous-requête par un expression CTE, puis utilisera cette dernière pour construire la requête :

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

Réf : 1995