在选择与unnest组合的postgresql数组元素时消耗了大量内存



当我在Postgresql9.5中创建一个临时表,其中一行包含一个不太小的int数组时

select array_agg(t.i) ids into temp table tmp1 from (select generate_series(1,100000) i) t;

下面的查询使用了数十GB的内存(并且占用了大量时间):

select ids[1] id_to, unnest(ids) id_from into temp table tmp2 from tmp1;

我没想到会这样,我想理解为什么选择一个数组元素和一个unnest需要这么多资源。如果不选择id[1],一切都会好起来。

作为一种变通方法,我使用了这个,它既高效又快速:

select array_agg(t.i) ids into temp table tmp1 from (select generate_series(1,80000) i) t;
alter table tmp1 add column id1 int;
update tmp1 set id1 = ids[1];
select id1 id_to, unnest(ids) id_from into temp table tmp2 from tmp1;

好吧,消耗内存的查询可能会为unnest(ids)中的每一行实例化一次大数组,然后从中提取第一个元素。我不确定它还能做什么。

我想可能有一个优化会注意到这是一个常数,但这通常不会是真的,所以这不是你会指望的那种事情

你也可以这样做:

WITH first AS (SELECT ids[1] AS elem1 FROM tmp1) 
SELECT elem1, unnest(ids) FROM tmp1, first;

不过,我很好奇你的用例。通常,如果要访问数组的各个元素,可能需要一个单独的表和一个联接。

最新更新