Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.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 plpgsql中二维数组处理速度慢_Performance_Postgresql_Plpgsql_Dynamic Arrays_Type 2 Dimension - Fatal编程技术网

Performance plpgsql中二维数组处理速度慢

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

我正在用PostgreSQL编写一个存储过程。该算法应该处理一个二维的
双精度
数字数组

据我所调查,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}}
    
    {{4,5,6},{7,8,9}}
    
    要使函数有用,请返回生成的数组。用一个简单的方法

    基于集合的高级版本 。正如@Craig在这个相关答案中所解释的那样,数组处理的性能特别差:

    我会使用基于集合的操作,更大的数字会更快

    多维数组的聚合函数 要生成多维数组,我们需要一个自定义聚合函数。或者只生成一维数组。这很简单,正如我们在这个相关的答案中得出的:

    替代功能 利用这一优点,我们可以构建一个简单的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!