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])
- 变更前:
由于以上
union_all
使用相同的 DataFramedf1
两次,因此生成的 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 ) )
- 变更后:
优化将检测到
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 ) )
参考:1995