Language SQL和Plpgsql在Postgresql Functions 的区别
上在一篇中测试看到postgresql中的function相同的逻辑,仅是create function时language在sql和plpgsql不同产生了不同的执行计划, 是因为postgresql是选择了不同的 SQL query “engine”, Postgresql支持多种不同的”runtime engines”执行不同的code,在Postgresql中创建function时语言支持SQL, PL/pgSQL, C ,C,Perl, Python, Ruby, Java 等,这是好多其它数据库不具备的,本篇总结一下在create function是的language在SQL和plpgsql之间的不同。
- 1, code逻辑一个纯SQL,短代码,没有查询block开销
- 2,一个标量查询,返回查询结果
- 3,SQL是有database server执行
- 4,执行一个DML不返回任何数据,returns void
- 5,会话单个调用
- 6,在较大查询的上下文中调用,并且足够简单,可以内联。
以下情况选择PlpgSQL language更好:
- 1, 一种过程语言,在语句块中处理更多的逻辑
- 2, 在一个会话中使用prepared statement所有的query plans可以cached,会话中多次调用
- 3, 需要SQL函数中没有的过程元素或变量时,如variables, loops, cursors, transaction command
- 4, 执行动态dynamic SQL
- 5, 记算结果被多次重用时
- 6, 需要捕捉错误时
- 7, trigger functions
- 8, 当包含DDL语句时,——因为SQL函数中的所有语句都是一次性解析的,而PL/pgSQL函数则按顺序计划并执行每个语句
例如:取分区名函数
highgo=# CREATE OR REPLACE FUNCTION sales_partition_function(date) highgo-# RETURNS TEXT AS $$ highgo$# DECLARE highgo$# partition_name TEXT; highgo$# BEGIN highgo$# partition_name := 'sales_' || to_char($1, 'YYYY_MM'); highgo$# RETURN partition_name; highgo$# END; highgo$# $$ LANGUAGE plpgsql; CREATE FUNCTION highgo=# CREATE OR REPLACE FUNCTION sales_partition_function1(partition_date DATE) highgo-# RETURNS TEXT highgo-# AS $$ highgo$# SELECT 'sales_' || to_char(partition_date, 'YYYY_MM'); highgo$# $$ LANGUAGE sql; CREATE FUNCTION highgo=# select sales_partition_function1(now()::date); sales_partition_function1 --------------------------- sales_2024_12 highgo=# select sales_partition_function(now()::date); sales_partition_function -------------------------- sales_2024_12 highgo=# explain (verbose) select sales_partition_function1(now()::date); QUERY PLAN --------------------------------------------------------------------------------------------------- Result (cost=0.00..0.02 rows=1 width=32) Output: ('sales_'::text || to_char(((now())::date)::timestamp with time zone, 'YYYY_MM'::text)) (2 rows) highgo=# explain (verbose) select sales_partition_function(now()::date); QUERY PLAN --------------------------------------------------- Result (cost=0.00..0.27 rows=1 width=32) Output: sales_partition_function((now())::date) (2 rows)
SQL是个查询语言,没有过程元素,如if, while, FUNCTION是包装SQL的一种方式,又可以使用不同的query “engine”,不同混合使用SQL或过程元素,需要在执行时切换”engine”,所以在create function时可以指定不同的language.用户提前声明,服务器知道以sql, plpgsql,python,C等引擎去执行。和在oracle中以DECLARE 开始声明,表未是一个匿名PLSQL 块一样, 需要服务器以不同的runtime engine去执行,因为MySQL中没有这东西,所以要创建存储过程或function。唯一不能清楚区分过程代码和“普通SQL”的DBMS产品是SQL Server的T-SQL支持混用。
据说在PostgreSQL:同样的请求,plpgsql语言比sql慢可以使用auto_explain 插件测试,配置postgresql.conf:
shared_preload_libraries = 'auto_explain' auto_explain.log_min_duration = 0 auto_explain.log_analyze = on auto_explain.log_buffers = on auto_explain.log_nested_statements = on track_functions = 'pl'
重启数据库,查看从SQL函数和PL/pgSQL函数调用语句时的执行计划和执行时间,看看是否可以发现差异。然后比较pg_stat_user_functions中的执行时间,比较函数的执行时间。
— reference https://www.itcodar.com/sql/difference-between-language-sql-and-language-plpgsql-in-postgresql-functions.html
对不起,这篇文章暂时关闭评论。