存储过程C语言与PL/pgSQL实现的效率对比

前端之家收集整理的这篇文章主要介绍了存储过程C语言与PL/pgSQL实现的效率对比前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

PL/pgsql已经有不少优化动作,比如

  1. for i in 1..100000 loop
  2. null;
  3. end loop;

这是可以瞬间完成的。

对于调用次数很多的自定义函数,用C实现肯定比PL/pgsql快,但到底能快多少?

1、日期相加函数

  1. create function pl_tsadd(timestamp with time zone,text,int)
  2. returns timestamp with time zone as
  3. $$
  4. declare
  5. intv interval;
  6. begin
  7. if $2 = 'yyyy' then
  8. intv = '1 year'::interval * $3;
  9. elsif $2 = 'mm' then
  10. intv = '1 month'::interval * $3;
  11. elsif $2 = 'dd' then
  12. intv = '1 day'::interval * $3;
  13. else
  14. return null;
  15. end if;
  16. return $1 + intv;
  17. end;
  18. $$
  19. language plpgsql STRICT immutable;

逻辑很简单,参数1是被相加的值,参数2是代表单位的字符,参数3是数量

10万次调用

  1. for i in 1..100000 loop
  2. tmp = pl_tsadd(now(),'dd',i);
  3. end loop;

结果

  1. flying=# select plfunc();
  2. plfunc
  3. --------
  4. (1 row)
  5.  
  6. Time: 320.965 ms

2、C语言实现同样逻辑

  1. PG_FUNCTION_INFO_V1(tsadd);
  2. Datum
  3. tsadd(PG_FUNCTION_ARGS)
  4. {
  5. Interval intv;
  6.  
  7. Datum tsdatumin = PG_GETARG_DATUM(0);
  8. char *tspartnam = text_to_cstring(PG_GETARG_TEXT_PP(1));
  9. int32 tspartnum = PG_GETARG_INT32(2);
  10.  
  11. memset(&intv,sizeof(intv));
  12.  
  13. if (pg_strcasecmp(tspartnam,"yyyy")==0)
  14. {
  15. intv.month = tspartnum * 12;
  16. }
  17. else if (pg_strcasecmp(tspartnam,"mm")==0)
  18. {
  19. intv.month = tspartnum;
  20. }
  21. else if (pg_strcasecmp(tspartnam,"dd")==0)
  22. {
  23. intv.day = tspartnum;
  24. }
  25. else
  26. PG_RETURN_NULL();
  27.  
  28. return DirectFunctionCall2(timestamptz_pl_interval,tsdatumin,IntervalPGetDatum(&intv));
  29. }

同样10万次

  1. flying=# select plfunc();
  2. plfunc
  3. --------
  4. (1 row)
  5.  
  6. Time: 67.277 ms

可以看出,C实现确实比PL/pgsql快好几倍,但代码实现是有更大难度的。PL/pgsql执行一次的时间已经非常微小,除非有极大次数的反复调用,否则似乎意义不大。

猜你在找的Postgre SQL相关文章