确保通过合并 2 个 bigint 数组创建数组中的唯一元素
Ensuring unique elements in array created from merging 2 bigint arrays
确保通过合并其他 2 个 bigint
数组创建的 bigint
数组中值的唯一性的最有效方法是什么?
例如,这个操作select ARRAY[1,2] || ARRAY[2, 3]
应该给出结果1,2,3
。我检查了扩展名 intarray
,发现它不适用于 bigint
。
您需要为此编写自己的函数。
create function concat_unique(p_array_one bigint[], p_array_two bigint[])
returns bigint[]
as
$$
select array_agg(x order by x)
from (
select x
from unnest(p_array_one) as t(x)
union
select x
from unnest(p_array_two) as t(x)
) t
$$
language sql
immutable;
然后:
select concat_unique(array[1,2], array[2,3,4]);
returns
concat_unique
-------------
{1,2,3,4}
既然你要求高效 - 函数可以优化:
您的问题中没有任何内容需要排序输出。所以:
CREATE OR REPLACE FUNCTION f_merge_uniq(bigint[], bigint[])
RETURNS bigint[] AS
$func$
SELECT ARRAY(
SELECT unnest()
UNION
SELECT unnest()
)
$func$ LANGUAGE sql IMMUTABLE;
但您也可以对其进行排序,而且几乎不会增加成本:
CREATE OR REPLACE FUNCTION f_merge_uniq_sort(bigint[], bigint[])
RETURNS bigint[] AS
$func$
SELECT ARRAY(
SELECT DISTINCT x
FROM (
SELECT unnest()
UNION ALL
SELECT unnest()
) sub(x)
ORDER BY 1
)
$func$ LANGUAGE sql IMMUTABLE;
db<>fiddle here
由于多种原因,计划和执行速度接近 两倍:
如果你 UNION
和 稍后 ORDER BY
,Postgres 会做额外的工作。
使用 (array_agg(x order by x)
) 对每个结果行进行排序是最坏的情况。对于一个结果行(如本例),它甚至更慢,因为有更多的开销。在子查询中排序(如果可能)通常更有效:
DISTINCT
操作马上就可以按排序了。我的第二个函数 f_merge_uniq_sort()
实现了这一点,因此它实际上与第一个 f_merge_uniq()
一样快,尽管它 returns 对数组进行了排序。 (在我使用 Postgres 12 的测试中似乎更快了一点!似乎 UNION
的效率略低于 DISTINCT
。)
ARRAY
构造函数比 array_agg()
.
快
确保通过合并其他 2 个 bigint
数组创建的 bigint
数组中值的唯一性的最有效方法是什么?
例如,这个操作select ARRAY[1,2] || ARRAY[2, 3]
应该给出结果1,2,3
。我检查了扩展名 intarray
,发现它不适用于 bigint
。
您需要为此编写自己的函数。
create function concat_unique(p_array_one bigint[], p_array_two bigint[])
returns bigint[]
as
$$
select array_agg(x order by x)
from (
select x
from unnest(p_array_one) as t(x)
union
select x
from unnest(p_array_two) as t(x)
) t
$$
language sql
immutable;
然后:
select concat_unique(array[1,2], array[2,3,4]);
returns
concat_unique
-------------
{1,2,3,4}
既然你要求高效 - 函数可以优化:
您的问题中没有任何内容需要排序输出。所以:
CREATE OR REPLACE FUNCTION f_merge_uniq(bigint[], bigint[])
RETURNS bigint[] AS
$func$
SELECT ARRAY(
SELECT unnest()
UNION
SELECT unnest()
)
$func$ LANGUAGE sql IMMUTABLE;
但您也可以对其进行排序,而且几乎不会增加成本:
CREATE OR REPLACE FUNCTION f_merge_uniq_sort(bigint[], bigint[])
RETURNS bigint[] AS
$func$
SELECT ARRAY(
SELECT DISTINCT x
FROM (
SELECT unnest()
UNION ALL
SELECT unnest()
) sub(x)
ORDER BY 1
)
$func$ LANGUAGE sql IMMUTABLE;
db<>fiddle here
由于多种原因,计划和执行速度接近 两倍:
如果你
UNION
和 稍后ORDER BY
,Postgres 会做额外的工作。 使用 (array_agg(x order by x)
) 对每个结果行进行排序是最坏的情况。对于一个结果行(如本例),它甚至更慢,因为有更多的开销。在子查询中排序(如果可能)通常更有效:DISTINCT
操作马上就可以按排序了。我的第二个函数f_merge_uniq_sort()
实现了这一点,因此它实际上与第一个f_merge_uniq()
一样快,尽管它 returns 对数组进行了排序。 (在我使用 Postgres 12 的测试中似乎更快了一点!似乎UNION
的效率略低于DISTINCT
。)
快ARRAY
构造函数比array_agg()
.