Я работаю с PostgreSQL, и он используется для отчетности. В настоящее время он настроен следующим образом:
Существует сложный запрос, который возвращает данные отчета, например:
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);
И моя проблема:
В чем может быть причина?
Хорошо, это было легко. Оказывается, база данных должна подготовить план запроса до того, как узнает о параметрах, что приводит к плохим результатам. Решением было использовать plpgsql и вернуть QUERY EXECUTE. Теперь производительность такая же, как и ожидалось.
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;