首页 > 解决方案 > 确保通过合并 2 个 bigint 数组创建的数组中的唯一元素

问题描述

bigint确保通过合并其他 2个数组创建的数组中值的唯一性的最有效方法是什么bigint

例如,这个操作select ARRAY[1,2] || ARRAY[2, 3]应该给出一个结果1,2,3。我检查了扩展名intarray,发现它不适用于bigint.

标签: arrayspostgresqlduplicatesbigintpostgresql-performance

解决方案


既然您要求高效-可以优化该功能:

您的问题中没有任何内容需要排序输出。所以:

CREATE OR REPLACE FUNCTION f_merge_uniq(bigint[], bigint[])
  RETURNS bigint[] AS
$func$
SELECT ARRAY(
  SELECT unnest($1)
  UNION
  SELECT unnest($2)
   )
$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($1)
      UNION ALL 
      SELECT unnest($2)
      ) sub(x)
   ORDER BY 1
   )
$func$  LANGUAGE sql IMMUTABLE;

db<>在这里摆弄

由于多种原因,计划和执行速度接近两倍:

  • 如果你UNION以后 ORDER BY Postgres 会做额外的工作。使用 ( ) 对每个结果行进行排序array_agg(x order by x)是最坏的情况。仅一个结果行(如本例中)甚至更慢,因为开销更大。在子查询中排序(如果可能)通常更有效:

  • DISTINCT操作可以立即基于排序。我的第二个函数f_merge_uniq_sort()实现了这一点,因此它实际上与第一个函数一样快,f_merge_uniq()即使它返回已排序的数组。(在我使用 Postgres 12 的测试中似乎更快一点!似乎UNION效率略低于DISTINCT.)

  • 构造ARRAY函数比.array_agg()


推荐阅读