在 SnowFlake DB 中并行执行存储过程中的 SQL 语句
Posted
技术标签:
【中文标题】在 SnowFlake DB 中并行执行存储过程中的 SQL 语句【英文标题】:Execution of SQL Statements inside Stored Procedure in Parallel in SnowFlake DB 【发布时间】:2020-10-07 06:28:10 【问题描述】:在 SnowFlake 中,是否有任何选项可以在存储过程中并行执行 sql 语句。我有一个存储过程(如下所示),它有 35 个 sql 语句,它们按顺序运行。我们计划减少时间,考虑并行执行所有这些。
实现这一目标的最佳方法是什么? (我所能想到的就是创建 35 个存储过程并同时从调度程序中调用它们)。想检查是否有任何 SnowFlake 功能的更好方法来实现这一点?
create or replace procedure SP_TEST()
returns string
language javascript
execute as CALLER
as
$$
try
var step_num = 0
step_num = 0
step_num++ //--#1
var sql_statement1 = snowflake.createStatement( sqlText: `INSERT INTO TGT_TBL select * from TBL_A` )
var sql_statement1_execute = sql_statement1.execute()
step_num++ //--#1
var sql_statement2 = snowflake.createStatement( sqlText: `INSERT INTO TGT_TBL select * from TBL_B` )
var sql_statement2_execute = sql_statement2.execute()
return "Completed "+step_num+" steps to load into TGT_TBL"
catch (err)
throw(err)
$$
;
【问题讨论】:
【参考方案1】:实际上它是连续的,因为您正在为每条语句运行 execute() 方法。
直接回答您的问题:在单个过程中实现并行化是不可能的,据我所知没有功能或特定方法。
但总的来说:增加仓库大小是节省一些时间的好方法,因为查询可能会运行得更快。它不是并行的,但速度更快。
在我看来,当您使用单个程序时,横向扩展(即使用多集群仓库)不会带来好处。
【讨论】:
【参考方案2】:作为创建 35 个任务的替代方案,您可以考虑创建一个任务来调用存储过程,该存储过程将创建 35 个任务来调用这些单独的查询。如果查询 SQL 可以从表中读取,或者其中的一部分可以通过 JavaScript 生成(例如带有日期的表名,即 CONNECT20200120 等),那么它可能是一个很好的自动化。
【讨论】:
能否详细解释一下。我知道我可以将查询保留在表中并从那里获取。但是,我怎样才能让这 35 条语句不按顺序运行呢? 您需要为并行运行的每个查询创建一个新任务。我在这里只看到一个问题,雪花不支持一次性任务。因此可以有一个使用“after”子句定义的主任务和子任务,以及一个在第一次运行后删除所有任务的更清洁任务。【参考方案3】:将您的 SP 分成几个(应该并行运行)并使用 SF 相关任务在主要部分完成后运行差异部分。
【讨论】:
【参考方案4】:如果您的目标是使用多个表 [TBL_A、TBL_B、...、TBL_35] 中的值填充表 TGT_TBL。我建议您使用第三方工具,例如 dbt、Informatica Cloud (IICS) 或此列表中您喜欢的任何工具 https://docs.snowflake.com/en/user-guide/ecosystem-etl.html。
事实上,Snowflake 存储过程甚至任务是有限的,也难以监控完整的编排/集成管道。
将 IICS 与 Pushdown Optimization 或 dbt 结合使用,您可以使用增量加载方法并在 Snowflake 上同时执行所有 35 条 sql 语句,而仍然具有 Snowflake 虚拟仓库的强大功能。
【讨论】:
以上是关于在 SnowFlake DB 中并行执行存储过程中的 SQL 语句的主要内容,如果未能解决你的问题,请参考以下文章
Snowflake /当存储过程作为OWNER执行时如何获取原始调用者