Snowflake存储过程与自定义函数的比较



我需要一些关于雪花存储过程与用户定义函数的最佳用例的指导。请问在哪种情况下其中一种比另一种更合适?我正试图为我的项目做出正确的选择。谢谢。

  • Snowflake存储过程是用JavaScript编写的。udf可以用JavaScript或SQL编写。
  • 允许存储过程返回值,但不要求存储过程返回值。
  • 存储过程作为独立语句调用,而不是作为语句的一部分(SELECT myfunc(x) vs CALL myproc(x))。
  • 存储过程返回的值与函数返回的值不同,不能直接在SQL中使用。

https://docs.snowflake.com/en/sql-reference/stored-procedures-overview.html differences-between-stored-procedures-and-udfs

和选择创建存储过程或UDF的指南:

https://docs.snowflake.com/en/sql-reference/stored-procedures-overview.html choosing-to-create-a-stored-procedure-or-a-udf

重要的区别在于对象在执行堆栈中的位置。雪花中的模式在数据库系统中非常典型:你有一个客户端程序向雪花发出SQL,在那里系统创建一个计划;然后,该计划被分发给执行引擎,执行引擎实际执行工作。

视觉:

[Client Program] --SQL--> [Planner] --plan--> [Execution Engine]

用户定义的函数是实际内置于计划并由执行引擎运行的东西。因为这实际上是计划的一部分,所以Snowflake将做一些事情,比如保证事务语义,并分发&跨仓库扩展工作

另一方面,存储过程实际上代替了客户端程序——它只是碰巧是存储的&在Snowflake内部执行。从管理的角度来看,这很好,但是Snowflake不能做任何特别的事情来扩展它,也不能为交易提供任何特殊的保证。这只是一个客户端程序。

给出一个具体的例子来说明它们之间的区别,假设我想在我的存储过程或函数中运行一个查询。对于一个过程来说,这没有问题:它非常像任何客户机发出的查询。

另一方面,也许我希望我的函数发出一个简单的查询,从用户的标识符查找用户名。我们不能,但假设我们能够将该查询包装在一个名为get_name()的函数中。现在我可以发出这样的查询:
SELECT id, get_name(id)
FROM my_table

但是让我们考虑一下当它运行时会发生什么。查询包含我的函数,因此包含此调用的计划将分布在我的仓库中。但是假设my_table有1M条记录:这意味着对get_name()的1M个调用和1M个查询将被发布给Snowflake。

哎哟。所以结果是你不能这样做。

不管怎样,对你的问题的一个冗长的回答。但归根结底还是要看你想要完成什么。如果你想要托管一个客户端程序,你需要一个过程。如果您正在寻找在查询中实际想要运行的宿主逻辑,则需要一个函数。有时你想扩展你的逻辑并在查询中运行它,但是,就像上面的例子一样,你不能——那么你需要更聪明地组织你的逻辑。

最新更新