plpgsql 编译执行
Oracle 的存储过程或函数提供了两种执行方式:
- 解释执行:将源代码逐条转换成目标代码,解释一条,执行一条的过程。PLPGSQL将语句翻译成中间形式的系统代码,并在运行时进行解释。
- 编译执行:将源代码一次性转换成目标代码,然后执行目标代码的过程。PLPGSQL将语句编译成动态库并存储在catalog中,运行时无须进行解释,运行速度更快。
KingbaseES plpgsql 通用也提供了编译执行方式,使得存储过程的执行效率大大提升。编译器只在第一次运行时进行编译,并加载到系统表 (pg_plpgsql_native_object)。我们来看以下例子:
1、创建存储过程
create or replace function caln( n integer ) returns bigint as $$ declare v_total bigint; begin v_total :=0; for i in 1..n loop v_total := v_total + i; end loop; return v_total; end; $$ language plpgsql;
2、Postgresql 执行情况
testdb=# \timing on Timing is on. testdb=# select caln(10000000); caln ---------------- 50000005000000 (1 row) Time: 2000.733 ms (00:02.001)
3、KingbaseES 执行情况
正常情况下执行效率:
test=# \timing on Timing is on. test=# select caln(10000000); caln ---------------- 50000005000000 (1 row) Time: 1954.474 ms (00:01.954)
启用编译执行:
test=# set plpgsql.enable_native_code=on; SET Time: 0.240 ms test=# select caln(10000000); caln ---------------- 50000005000000 (1 row) Time: 130.605 ms
4、对于执行大量SQL的效果
例子:
create or replace procedure proc01 as $$ declare cnt integer; begin for i in 1..1000000 loop select count(*) into cnt from t1; end loop; end; $$ language plpgsql
执行结果:
test=# call proc01(); CALL Time: 6198.621 ms (00:06.199) test=# set plpgsql.enable_native_code=on; SET Time: 0.529 ms test=# call proc01(); CALL Time: 304.246 ms
5、结论:
1、plpgsql 的编译执行会有很大的性能提升,特别是主要消耗在SQL解析上的SQL,对于大量时间消耗在SQL 执行上的过程,提升不大。
2、只适用于plpgsql,对于 plsql 无效。后续版本会支持plsql 编译执行。
KINGBASE研究院