PostgreSQL原始查询vs“函数返回TABLE” – 疯狂的性能差异。 为什么?

我使用PostgreSQL,它用于报告。 目前configuration的方式如下:

有一个复杂的查询返回报表数据,如下所示:

select Column1 as Name1, Column2 as Name2 from sometable tbl inner join ... where ... and ... and $1 <= somedate and $2 >= somedate group by ... order by ...; 

有一个利用这个查询的函数,并且是这样定义的

 CREATE OR REPLACE FUNCTION GetMyReport(IN fromdate timestamp without time zone, IN todate timestamp without time zone) RETURNS TABLE(Name1 character varying, Name2 character varying) AS $BODY$ --query start select Column1 as Name1, Column2 as Name2 from sometable tbl inner join ... where ... and ... and $1 <= somedate and $2 >= somedate group by ... order by ...; --query end $BODY$ LANGUAGE sql VOLATILE COST 10 ROWS 1000; 

最后,当报告应用程序调用函数时,它发送以下SQL:

 select null::text as Name1, Name2 from GetMyReport ('2012-05-28T12:19:39.0000000+11:00'::timestamp, '2012-05-28T12:19:44.0000000+11:00'::timestamp); 

而我的问题是:

  • 当我只对数据库运行“查询”时,运行速度非常快。 事实上,如果返回的数据相当小,几秒钟之内
  • 当我运行从报告应用程序传递的sql时,每次都需要疯狂的时间来运行。 实际上,对于查询以秒为单位返回的相同数据,超过10分钟。
  • 事实上,我可以运行原始查询,需要几毫秒,运行的function – 约10分钟,再次运行查询 – 毫秒,运行function – 再次10分钟,所有参数完全相同。

这可能是什么原因?

好的,那很简单。 事实certificate,数据库必须在知道参数之前准备查询计划,这会导致错误的结果。 解决scheme是使用plpgsql并返回QUERY EXECUTE。 现在的performance如预期一样。

 CREATE OR REPLACE FUNCTION GetMyReport(IN fromdate timestamp without time zone, IN todate timestamp without time zone) RETURNS TABLE(Name1 character varying, Name2 character varying) AS $BODY$ BEGIN RETURN QUERY EXECUTE' select Column1 as Name1, Column2 as Name2 from sometable tbl inner join ... where ... and ... and $1 <= somedate and $2 >= somedate group by ... order by ...;' USING $1, $2 END $BODY$ LANGUAGE plpgsql VOLATILE COST 10 ROWS 1000;