Arrays 如何优化heroku上的intersect

Arrays 如何优化heroku上的intersect,arrays,postgresql,heroku,Arrays,Postgresql,Heroku,我有一个postgresql查询,检查两个数组的交集长度。我的查询的非常简化的版本如下所示: SELECT array_length(users.array & Array[1,2,3,4]) from users; 它是更大查询的一部分,但这在这里并不重要。它在我的本地数据库上运行良好,但在heroku上,intarray扩展并没有被列入白名单 我发现了与数组相交的简单函数,但与&操作符相比,它的速度相当慢 CREATE OR REPLACE FUNCTION array_inter

我有一个postgresql查询,检查两个数组的交集长度。我的查询的非常简化的版本如下所示:

SELECT array_length(users.array & Array[1,2,3,4]) from users;
它是更大查询的一部分,但这在这里并不重要。它在我的本地数据库上运行良好,但在heroku上,intarray扩展并没有被列入白名单

我发现了与数组相交的简单函数,但与
&
操作符相比,它的速度相当慢

CREATE OR REPLACE FUNCTION array_intersect(anyarray, anyarray)
RETURNS anyarray AS $$
  SELECT ARRAY( SELECT * FROM UNNEST( $1 ) WHERE UNNEST = ANY( $2 ) );
$$ LANGUAGE sql;
在我的表的大约2000条记录上,使用
&
操作符大约需要
50ms
,使用上述函数大约需要
150ms
。我想比较尽可能多的记录,这个函数的伸缩性不如“&”操作符


有什么方法可以更快地完成这项工作,或者将intarray添加到heroku中吗?

我想这可能取决于您的查询的其余部分,以及需要如何优化它

我的第一次尝试是使用
unnest
intersect
创建所有不安全长度的CTE。。。然后在需要的地方从主表达式中的CTE中获取值。。。大致如下:

WITH merged AS (
    SELECT * FROM unnest(ARRAY[1,2,3]) 
    INTERSECT 
    SELECT * FROM unnest(ARRAY[1])
) 
SELECT count(*) as length FROM merged;
如果这不合适,我会尝试一个函数(正如您所做的那样),但由于我只对长度感兴趣,我会让函数返回该值(以避免不必要地转换为数组并返回):


如果这仍然不够好,那么我会考虑创建一个中间表来存储/缓存数据更改时通过触发器更新的相交数组的长度,然后使用这个中间表在我的主查询中查找所需的长度,而无需执行任何并集。

感谢您的评论。我有数组交集函数,但我不想做计数函数。我希望有办法在heroku上使用
&
操作符,但我想这已经是我能做到的了。
CREATE OR REPLACE FUNCTION array_count_intersects(anyarray, anyarray)
RETURNS bigint AS $$
    SELECT count(*) FROM (
        SELECT * FROM UNNEST($1) WHERE UNNEST = ANY($2)
    ) as merg;
$$ LANGUAGE sql;

SELECT array_count_intersects(ARRAY[1,2,3], ARRAY[1]);