Snowflake过程递归调用在Parallel中运行



我需要找到一种并行触发Snowflake过程调用的方法。一个很好的例子是,在表加载过程中,在SQL的主块开始运行之前,三个初始插入都会进入同一个临时表。因为这三个步骤并不相互依赖,所以我考虑将它们并行运行。当前的代码库让它们按顺序运行,当我们迁移到Snowflake时,我们正在构建一个Javascript Procedure框架来运行所有迁移的查询,是否可以触发Snowflak过程并行递归运行?

下面是一个函数,它只运行两个相互独立的命令,并且可以并行运行。

create or replace procedure stackOverflowProcedure (inputArray array) 
returns varchar
language javascript
strict
as
$$
var demoIterator = 1;
while (demoIterator <= INPUTARRAY.length) {
snowflake.createStatement({sqlText: INPUTARRAY[demoIterator - 1]}).execute();
demoIterator = demoIterator + 1;
};
$$;
call stackOverflowProcedure(array_construct($$insert into temp_table select * from source_table_1;$$,$$insert into temp_table select * from source_table_2$$));

是的,我一直使用它来并行运行存储过程。

步骤1:如果加载有大量文件(仓库中每个节点有8个并行加载的文件…nodes=大小调整表单中的信用额度(,请创建尽可能多的仓库以并行运行加载存储过程。

步骤2:如果并行运行是安全的,则为每个存储过程或同一存储过程的实例创建一个任务。如果您正在运行带有大量文件的加载,请将每个任务设置为使用不同的仓库。

第三步:安排你的活动同时进行。他们可能不会在同一时间开始,但他们应该很接近。

您有几个选项:

使用外部协调器

具有内置DAG功能的东西,如DBT。

将您的选择合并为一个插入

您可以使用UNIONUNION ALL将它们附加在一起,而不是对同一个表/结构执行单独的插入。

注意:这是唯一一个可以让您轻松知道所有插入何时完成的选项,因为其他选项是异步运行的(您不容易知道它们何时全部完成(

INSERT INTO temp_table
SELECT * FROM source_table_1
UNION ALL
SELECT * FROM source_table_2;

如果你的选择有点过于复杂,并且你想稍微清理一下代码,你也可以使用CTEs:

INSERT INTO temp_table
WITH query1 AS (
SELECT ... FROM ...
), query2 AS (
SELECT ... FROM ...
)
SELECT * FROM query1
UNION ALL
SELECT * FROM query2;

调用EXECUTE TASK

您可以为每个查询创建一个任务,并调用EXECUTE TASK,而不是直接执行SQL查询。以这种方式触发的任务异步运行(命令不等待任务完成,甚至不等待任务启动(,这意味着它们基本上是并行运行的。

注意:您可以创建没有时间表或触发器的任务,因此它们只能通过EXECUTE TASK手动触发

call stackOverflowProcedure(
array_construct(
'EXECUTE TASK task_1;',
'EXECUTE TASK task_2;'
)
);

使用任务树

正如@mikewalton在评论中提到的,您可以创建一个简单的任务树,具有相同父任务的任务将并行执行。

CREATE TASK parent_task
[ PARAMETERS ]
AS
$$
SELECT 1;
$$;
CREATE TASK child_task_1 AFTER parent_task ...;
CREATE TASK child_task_2 AFTER parent_task ...;
CREATE TASK child_task_3 AFTER parent_task ...;

最新更新