2016-12-30 46 views
1

我有一个非常大的数组,我用Apache Madlib进行了计算,我想对该2D数组中的每个数组应用一个操作。如何在PostgreSQL中将2d数组快速放入1d数组中?

我发现的代码可以帮助我从this related answer不知情的代码。然而,这个真正大的二维数组(150,000 + 1d浮点数组)的代码速度很慢。尽管unnest()只需几秒钟即可运行,即使在等待几分钟后代码仍未完成。

当然,必须有一种更快的方式将大型2d阵列拆分成更小的1d阵列?奖励点如果该解决方案使用Apache Madlib。我这样做,找一个铅埋称为deconstruct_2d_array的文档中,但是当我试图呼吁矩阵功能,它失败,出现以下错误:

ERROR: Function "deconstruct_2d_array(double precision[])": Invalid type conversion. Internal composite type has more elements than backend composite type.

回答

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):

ERROR: FOREACH expression must not be null

+0

谢谢,@Erwin,非常实用!它只需要被标记为STRICT。 – IamIC

+0

@IamIC:谢谢,我补充说。 –

0

现在有一个内置马德利布功能来做到这一点 - 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) 

然后调用函数UNNEST:

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阵列

相关问题