如何在PostgreSQL中快速将2d数组转换为1d数组?

时间:2016-12-30 20:36:51

标签: sql arrays performance postgresql madlib

我有一个非常大的数组,我使用Apache Madlib进行计算,我想对该二维数组中的每个单独数组应用一个操作。

我找到的代码可以帮助我从this related answer中删除它。但是,这个非常大的2d阵列(150,000+ 1d浮点数组)的代码速度非常慢。虽然unnest()只需几秒钟即可运行,但即使在等待几分钟后代码仍未完成。

当然,必须有一种更快的方法来将大型2d阵列排除在较小的1d阵列中?如果该解决方案使用Apache Madlib,则为奖励点。我确实在名为deconstruct_2d_array的文档中找到了一个潜在客户,然而,当我尝试在矩阵上调用该函数时,它失败并出现以下错误:

  

错误:功能" deconstruct_2d_array(双精度[])":无效   类型转换。内部复合类型的元素多于   后端复合类型。

2 个答案:

答案 0 :(得分:2)

您在我的旧答案中找到的功能对于大型数组而言不能很好地扩展。我从未想过你的大小数组,而应该是一组(一个表)。

尽管如此,这个plpgsql函数替换了referenced answer中的函数。需要Postgres 9.1或更高版本。

CREATE OR REPLACE FUNCTION unnest_2d_1d(ANYARRAY, OUT a ANYARRAY)
  RETURNS SETOF ANYARRAY AS
$func$
BEGIN
   FOREACH a SLICE 1 IN ARRAY $1 LOOP
      RETURN NEXT;
   END LOOP;
END
$func$  LANGUAGE plpgsql IMMUTABLE STRICT;

在Postgres 9.6的大型2d阵列上测试速度提高了40倍。

STRICT以避免NULL输入的异常(如commented by IamIC):

  

错误:FOREACH表达式不能为空

答案 1 :(得分:1)

现在有一个内置的MADlib函数来执行此操作 - array_unnest_2d_to_1d,它是在1.11版本中引入的: http://madlib.incubator.apache.org/docs/latest/array__ops_8sql__in.html#af057b589f2a2cb1095caa99feaeb3d70

以下是一个示例用法:

CREATE TABLE test1 (pid int, points double precision[]);
INSERT INTO test1 VALUES
(100,  '{{1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}, {7.0, 8.0, 9.0}}'),
(101,  '{{11.0, 12.0, 13.0}, {14.0, 15.0, 16.0}, {17.0, 18.0, 19.0}}'),
(102,  '{{21.0, 22.0, 23.0}, {24.0, 25.0, 26.0}, {27.0, 28.0, 29.0}}');
SELECT * FROM test1;

产生

 pid |               points               
-----+------------------------------------
 100 | {{1,2,3},{4,5,6},{7,8,9}}
 101 | {{11,12,13},{14,15,16},{17,18,19}}
 102 | {{21,22,23},{24,25,26},{27,28,29}}
(3 rows)

然后调用不需要的函数:

SELECT pid, (madlib.array_unnest_2d_to_1d(points)).* 
FROM test1 ORDER BY pid, unnest_row_id;

产生

pid | unnest_row_id | unnest_result 
-----+---------------+---------------
 100 |             1 | {1,2,3}
 100 |             2 | {4,5,6}
 100 |             3 | {7,8,9}
 101 |             1 | {11,12,13}
 101 |             2 | {14,15,16}
 101 |             3 | {17,18,19}
 102 |             1 | {21,22,23}
 102 |             2 | {24,25,26}
 102 |             3 | {27,28,29}
(9 rows)

其中unnest_row_id是2D数组的索引