我需要找到一种并行触发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。
将您的选择合并为一个插入
您可以使用UNION
或UNION 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 ...;