Performance plpgsql中二维数组处理速度慢
我正在用PostgreSQL编写一个存储过程。该算法应该处理一个二维的Performance plpgsql中二维数组处理速度慢,performance,postgresql,plpgsql,dynamic-arrays,type-2-dimension,Performance,Postgresql,Plpgsql,Dynamic Arrays,Type 2 Dimension,我正在用PostgreSQL编写一个存储过程。该算法应该处理一个二维的双精度数字数组 据我所调查,Postgres中的数组操作是通用的,而且相当繁重。我试图证明的这个简单的例子计算量过大 例如: CREATE OR REPLACE FUNCTION fill_2d_array( rows integer, cols integer) RETURNS integer AS $BODY$ DECLARE img double precision[][]; i integer; j int
双精度
数字数组
据我所调查,Postgres中的数组操作是通用的,而且相当繁重。我试图证明的这个简单的例子计算量过大
例如:
CREATE OR REPLACE FUNCTION fill_2d_array( rows integer, cols integer)
RETURNS integer AS
$BODY$
DECLARE
img double precision[][];
i integer; j integer;
cont integer;
BEGIN
img := ARRAY( SELECT 0 FROM generate_series(1, filas * columnas) ) ;
cont:= 0;
For i IN 1..rows LOOP
For j IN 1..cols LOOP
img[i * cols + j] := (i * cols + j)::double precision;
cont := cont + 1;
END LOOP;
END LOOP;
return cont;
END;
$BODY$
LANGUAGE plpgsql;
有人能帮我找到处理二维数组的替代路径或改进方法吗?程序功能
基本问题
- 声明数组变量的维度,如二维数组的
,仅用于文档。考虑这个相关答案的细节:float8[][]
- 您混淆了一维数组和二维数组。声明二维数组(无效)时,只能将其设置为一维数组
- 要初始化数组,请使用:
本例生成二维数组-与错误语句相反,生成一维数组:
电话: 结果:img := ARRAY( SELECT 0 FROM generate_series(1, rows* cols) );{{4,5,6},{7,8,9}}
要使函数有用,请返回生成的数组。用一个简单的方法 基于集合的高级版本 。正如@Craig在这个相关答案中所解释的那样,数组处理的性能特别差:{{4,5,6},{7,8,9}}
我会使用基于集合的操作,更大的数字会更快 多维数组的聚合函数 要生成多维数组,我们需要一个自定义聚合函数。或者只生成一维数组。这很简单,正如我们在这个相关的答案中得出的:
替代功能 利用这一优点,我们可以构建一个简单的SQL函数,执行与上述相同的操作:
电话: 结果:CREATE OR REPLACE FUNCTION f_array_fill_sql(_rows integer, _cols integer) RETURNS float8[][] AS $func$ SELECT array_agg_mult(ARRAY[arr1]) AS arr2 FROM ( SELECT array_agg((i * $2 + j)::float8) AS arr1 FROM generate_series(1, $1) i CROSS JOIN generate_series(1, $2) j GROUP BY i ORDER BY i ) sub $func$ LANGUAGE sql
{{4,5,6},{7,8,9}}
比较 对于较小的数字,性能上的差异可以忽略不计。但是第一个变体(即使现在已经优化)随着数量的增加而迅速退化。尝试:{{4,5,6},{7,8,9}}
EXPLAIN ANALYZE SELECT f_array_fill(100,100) EXPLAIN ANALYZE SELECT f_array_fill_sql(100,100) -- ~ 50x faster!
我说不清你想做什么。。。为什么不能用arrayagg()代替循环?
和filas
是未定义的。我想应该是columnas
和行
?请描述一下你想做什么。由于您只返回一个整数,整个操作似乎毫无意义?对数组字段的访问速度相对较快(不像C确定的那么快),但是数组更新大数组的速度非常慢,因此(此时)数组(以及Postgres中的所有对象)都是不可变的结构。任何更新都意味着创建新的更新。此功能将被修复(可能)-补丁在commitfest@PavelStehule中:我已经读过了。令人兴奋的消息。干得好!:)列
SELECT f_array_fill_sql(3,4);
{{4,5,6},{7,8,9}}
EXPLAIN ANALYZE SELECT f_array_fill(100,100) EXPLAIN ANALYZE SELECT f_array_fill_sql(100,100) -- ~ 50x faster!