Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 为什么快速函数在任何函数中都会变慢?_Performance_Postgresql - Fatal编程技术网

Performance 为什么快速函数在任何函数中都会变慢?

Performance 为什么快速函数在任何函数中都会变慢?,performance,postgresql,Performance,Postgresql,我有一个返回整数数组的函数。如果我打电话: select getmun_gaz(12554) 它在33毫秒内返回一个“整数[]”: {1547,1564} 与我得到的结果完全相同: select array[1547,1564] 相同的类型(整数[]),相同的值({15471564}),只有轻微的时间差。那么,为什么这会立即生效: select * from loc where id = any(array[1547,1564]) 但这需要2分钟以上 select * from loc

我有一个返回整数数组的函数。如果我打电话:

select getmun_gaz(12554)
它在33毫秒内返回一个“整数[]”:

{1547,1564}
与我得到的结果完全相同:

select array[1547,1564]
相同的类型(整数[]),相同的值({15471564}),只有轻微的时间差。那么,为什么这会立即生效:

select *
from loc
where id = any(array[1547,1564])
但这需要2分钟以上

select *
from loc
where id = any(getmun_gaz(12554))
如果需要,我将发布函数的内容和表的结构。这个数据来源的表格确实很大,但这在开始时没有什么区别,那么为什么最终会这样呢

职能:

CREATE OR REPLACE FUNCTION getmun_gaz(gaz_id integer)
  RETURNS integer[] AS
$BODY$
with recursive locpais as (
    select l.id, l.nome, l.tipo tid, lt.tipo, lp.pai, 1 as profund
    from loc l
    left join locpai lp on lp.loc = l.id
    left join loctipo lt on lt.id = l.tipo
    where l.id = gaz_id
    union
    select l.id, l.nome, l.tipo tid, lt.tipo, lp.pai, profund+1
    from loc l
    left join locpai lp on lp.loc = l.id
    left join loctipo lt on lt.id = l.tipo
    join locpais p on (l.id = p.pai)
)
select array_agg(id) from locpais
where tid = 8
$BODY$
  LANGUAGE sql VOLATILE
  COST 100;

如果需要,我将稍后添加表结构。现在得走了。

第二个函数的问题是,如果函数不是不可变的db需要计算每行的值


any(数组[15471564])不同的是,
是一个常量。

第二个数组的问题是,如果函数不是不可变的db需要为每一行计算他的值


any(数组[15471564])不同的是,
是一个常量。

这是因为函数的

将函数声明为VOLATILE会告诉Postgres它有副作用,并且/或者每次调用它时它的值都会改变(例如,
random()
)。这意味着在您的查询中,Postgres必须为
loc
表中的每一行调用一次,并且不能使用
id
上的索引来加快速度


如果您的函数只包含
SELECT
s,而没有调用其他
VOLATILE
函数,则可以将其声明为
稳定
。这告诉Postgres,当在一个查询中多次调用时,结果将保持不变;查询计划器现在可以在开始时调用它一次,并为每个
id
比较重复使用该值,还可以通过使用索引优化大部分比较。

这是因为函数的

将函数声明为VOLATILE会告诉Postgres它有副作用,并且/或者每次调用它时它的值都会改变(例如,
random()
)。这意味着在您的查询中,Postgres必须为
loc
表中的每一行调用一次,并且不能使用
id
上的索引来加快速度


如果您的函数只包含
SELECT
s,而没有调用其他
VOLATILE
函数,则可以将其声明为
稳定
。这告诉Postgres,当在一个查询中多次调用时,结果将保持不变;查询计划器现在可以在开始时调用它一次,并为每个
id
比较重复使用该值,还可以通过使用索引优化大部分比较。

什么是
getnum\u gaz()
?是的,您应该发布该函数,因为这里当然没有人知道其中包含什么。尝试将您的函数声明为
稳定的
不可变的
,看起来您解决了它,@Abelisto。将此作为答案发布,如果有效,绿色复选标记是您的。@Rodrigo这里似乎已经有了正确的答案:)只需选择更适合您功能的开关(它必须是
稳定的
IMO)。什么是
getnum_gaz()
?是的,您应该发布该函数,因为这里当然没有人知道其中包含什么。尝试将您的函数声明为
稳定的
不可变的
,看起来您解决了它,@Abelisto。将此作为答案张贴,如果有效,绿色复选标记是您的。@Rodrigo这里似乎已经有了正确的答案:)只需选择更适合您功能的开关(它必须是
稳定的
IMO)。为什么要整张表?getmun_gaz(12554)只返回两个值,速度非常快!在底层逻辑中有一些东西我仍然没有得到。是的,我认为你在比较不同的东西,问题是如果你的函数不是INMMUTABLE,db必须为每一行计算它。相反,
array[]
是一个常量。为什么要整张表?getmun_gaz(12554)只返回两个值,速度非常快!在底层逻辑中有一些东西我仍然没有得到。是的,我认为你在比较不同的东西,问题是如果你的函数不是INMMUTABLE,db必须为每一行计算它。相反,
array[]
是一个常量。