Postgresql使用相同参数超过
我创建了一个函数。我想在查询中的不同位置使用相同的参数。当我正常运行查询时,我得到的查询结果是31毫秒。当我在函数中使用不返回结果的参数时。查询正在运行。我怎样才能解决这个问题 查询结果为31毫秒Postgresql使用相同参数超过,postgresql,Postgresql,我创建了一个函数。我想在查询中的不同位置使用相同的参数。当我正常运行查询时,我得到的查询结果是31毫秒。当我在函数中使用不返回结果的参数时。查询正在运行。我怎样才能解决这个问题 查询结果为31毫秒 SELECT t2.id, t2.sk, t2.sk_code, t2.yl, st_distance(st_transform(st_setsrid(st_point(28.862966895103455, 41.02119524147813), 4326), 500
SELECT t2.id, t2.sk, t2.sk_code, t2.yl,
st_distance(st_transform(st_setsrid(st_point(28.862966895103455, 41.02119524147813), 4326), 500000), t2.geom) AS mf, t2.rc::INTEGER
FROM public.rc t2
where st_intersects(st_buffer(st_transform(st_setsrid(st_point(28.862966895103455, 41.02119524147813), 4326), 500000),400),t2.geom)= true and
st_distance(st_transform(st_setsrid(st_point(28.862966895103455, 41.02119524147813), 4326), 500000), t2.geom) =
(SELECT distinct st_distance(st_transform(st_setsrid(st_point(28.862966895103455, 41.02119524147813), 4326), 500000), t2.geom) from
public.rc t2 where st_intersects(st_buffer(st_transform(st_setsrid(st_point(28.862966895103455, 41.02119524147813), 4326), 500000),400),t2.geom)
=true
group by st_distance(st_transform(st_setsrid(st_point(28.862966895103455, 41.02119524147813), 4326), 500000), t2.geom)
ORDER BY st_distance(st_transform(st_setsrid(st_point(28.862966895103455, 41.02119524147813), 4326), 500000), t2.geom) ASC
limit 1 )
ORDER BY yl asc ,st_distance(st_transform(st_setsrid(st_point(28.862966895103455, 41.02119524147813), 4326), 500000), t2.geom) ASC;
函数不能返回正在运行的任何内容
CREATE OR REPLACE FUNCTION public.getplaces(
IN latx double precision,
IN lngx double precision,
OUT id integer,
OUT sk character varying,
OUT sk_code double precision,
OUT yl double precision,
OUT mf double precision,
OUT rc integer)
RETURNS SETOF record AS
$BODY$
SELECT t2.id, t2.sk, t2.sk_code, t2.yl,
st_distance(st_transform(st_setsrid(st_point(getplaces.lngx, getplaces.latx), 4326), 500000), t2.geom) AS mf, t2.rc::INTEGER
FROM public.rc t2
where st_intersects(st_buffer(st_transform(st_setsrid(st_point(getplaces.lngx, getplaces.latx), 4326), 500000),400),t2.geom)= true and
st_distance(st_transform(st_setsrid(st_point(getplaces.lngx, getplaces.latx), 4326), 500000), t2.geom) =
(SELECT distinct st_distance(st_transform(st_setsrid(st_point(getplaces.lngx, getplaces.latx), 4326), 500000), t2.geom) from
public.rc t2 where st_intersects(st_buffer(st_transform(st_setsrid(st_point(getplaces.lngx, getplaces.latx), 4326), 500000),400),t2.geom)
=true
group by st_distance(st_transform(st_setsrid(st_point(getplaces.lngx, getplaces.latx), 4326), 500000), t2.geom)
ORDER BY st_distance(st_transform(st_setsrid(st_point(getplaces.lngx, getplaces.latx), 4326), 500000), t2.geom) ASC
limit 1 )
ORDER BY yl asc ,st_distance(st_transform(st_setsrid(st_point(getplaces.lngx, getplaces.latx), 4326), 500000), t2.geom) ASC;
$BODY$
LANGUAGE sql VOLATILE
COST 1000
ROWS 1000;
试着找出执行计划的不同之处 首先,跑步
EXPLAIN (ANALYZE, BUFFERS) SELECT t2.id, ...;
将查询与运行“fast”的常量一起使用
更困难的部分是找出函数内部查询的执行计划。您可以使用准备好的语句来执行此操作:
PREPARE stmt(double precision, double precision) AS
SELECT t2.id, t2.sk, ...
... st_point($1, $2) ...;
只需将函数参数出现的所有位置替换为$1
或$2
然后运行:
EXPLAIN EXECUTE stmt(28.862966895103455, 41.02119524147813);
您应该得到一个包含$1
和$2
的计划,而不是参数值
如果您可以在这里运行EXPLAIN(ANALYZE)
,那就太好了,但是如果执行时间太长,那就不是一个选项
然后比较执行计划,看看第二个计划有什么不同。也许你可以改进这个陈述,使它更有效地做你想做的事情
如果无法通过这种方式找到解决方案,可以在PL/pgSQL函数中使用动态SQL语句。应具有与第一条语句相同的执行计划:
BEGIN
RETURN QUERY EXECUTE
'SELECT t2.id, t2.sk, ...
...st_point($1, $2) ...'
USING getplaces.lngx, getplaces.latx;
END;
找出这两个查询的执行计划。对于带参数的查询,使用
PREPARE
和EXPLAIN
将执行
六次,直到计划中出现$1
为止,创建一个带参数的预处理语句。如果后一个计划实际上更糟糕,请使用动态SQL。我使用了developer.getplaces(40.944709258659690,29.160144542327885)中的EXPLAIN Select*,结果是“getplaces上的函数扫描(成本=0.25..10.25行=1000宽度=162)”另外,我在查询中使用了execute格式,没有改变任何东西。我已经在回答中解释过了-注释太短了。谢谢你的帮助。