Snowpark Python: Eliminate repeated subqueries in Snowpark-generated queries (Canceled)

注意

This BCR is canceled and removed from the 2025_04 Bundle (Generally enabled).

重复消除子查询可识别查询计划中相同的子 DataFrames 查询,并使用公用表表达式 (CTEs) 来构造最终查询。在编译时间超过一秒的查询中,将近一半包含至少一个冗余子查询。这种优化的好处会随着已识别的重复子查询的数量和复杂性而变化。

  • 诊断步骤:

    • 以前运行时没有错误的 Snowpark 数据管道上的 SQL 编译错误。

    • 因 SQL 生成中的错误而生成的错误结果。

  • 解决措施:

    • 降级到旧版本的 Snowpark 客户端可以解决问题。

    • 取消设置参数 PYTHON_SNOWPARK_USE_CTE_OPTIMIZATION_VERSION 可以解决问题。

      为了不受此次变更的影响,请将基于 Snowpark 的工作流程固定到低于 1.31.1 的 Snowpark Python 版本。例如,如果您使用的是 Python 存储过程,请在创建存储过程时进行设置 PACKAGES=('snowflake-snowpark-python==1.30.0')。对于 Snowflake Notebook 或 Python 工作表,请切换到低于 1.31.1 的 Snowpark Python 版本。

为了演示新旧行为的区别,可以考虑 Snowpark Python 中的以下 DataFrame 转换:

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
变更前:

由于以上 union_all 使用相同的 DataFrame df1 两次,因此生成的 SQL 查询将重复底层子查询两次:

( 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
变更后:

优化将检测到 df1 已使用两次,将使用 CTE 表达式替换子查询,然后使用该表达式来构建查询:

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

参考:1995

语言: 中文