Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 不使用@>;查找包含另一个数组子集的数组;使用postgreSQL_Arrays_Postgresql_Greenplum - Fatal编程技术网

Arrays 不使用@>;查找包含另一个数组子集的数组;使用postgreSQL

Arrays 不使用@>;查找包含另一个数组子集的数组;使用postgreSQL,arrays,postgresql,greenplum,Arrays,Postgresql,Greenplum,我有一个带有1.5 MM记录的表格。每个记录都有一个行号和一个数组,数组中的元素介于1和1000之间。我试图找到所有的数组,它们是较大数组的子集 当我使用下面的代码时,我得到了一个错误:语句需要的资源比资源队列允许的要多(可能是因为有超过一万亿种可能的组合): select a.array as dup from table a left join table b on b.array @> a.array and a.row_number <>

我有一个带有
1.5 MM
记录的表格。每个记录都有一个
行号
和一个
数组
,数组中的元素介于
1和1000之间。我试图找到所有的数组,它们是较大数组的子集

当我使用下面的代码时,我得到了一个错误:语句需要的资源比资源队列允许的要多(可能是因为有超过一万亿种可能的组合):

select
   a.array as dup
from
   table a
left join
    table  b
on
  b.array @> a.array 
  and a.row_number <> b.row_number
选择
a、 作为dup的数组
从…起
表a
左连接
表b
在…上
b、 数组@>a.array
a.排号b.排号

除了使用
@>
之外,还有没有更有效的方法来识别哪些数组是其他数组的子集并标记它们以便删除?

好吧,如果没有索引的适当支持,我看不到如何在单个声明性SQL语句中有效地执行此操作。我不知道这对GIN索引的效果如何,但是使用GIN索引肯定可以避免比较每一对可能的行的需要

我要做的第一件事是仔细调查您可以使用的索引类型,并在必要时尝试创建一个索引


如果这不起作用,我想到的第一件事,从程序上讲,将是对所有数组进行排序,然后按数组上的分级词典顺序对行进行排序。然后从最短的数组开始,按如下方式向上操作:例如,对于[1,4,9],检查所有长度为的数组。示例代码表明,您只对查找表另一行中任何其他数组的子集感兴趣

但是,使用
JOIN
的查询将返回所有组合,可能是相乘的结果

请尝试一个
存在的
半联接,只返回一次符合条件的行:

并遍历该表。应该对这种情况有效


旁白:很遗憾,您的派生(Greenplum)似乎不支持GIN索引,这将使此操作更快。(虽然索引本身会很大)

您是否尝试过在数组列上创建GIN索引?我们的数据库不支持GIN索引-它在Greenplum版本上。如果您想知道与此类型数据库相关的行号,则可以使用任意顺序手动分配,但每次我从表中提取数据时都是一样的。谢谢你的建议。不幸的是,只有当我将table_id设置为0到500之间时,才能使用table_id,这意味着需要大量的迭代。然而,通过使用limit100000和语句末尾,我能够说服系统运行我的代码,这意味着迭代次数要少得多。
SELECT a.array as dup
FROM   table a
WHERE  EXISTS (
   SELECT 1
   FROM   table b
   WHERE  a.array <@ b.array
   AND    a.row_number <> b.row_number
   );
AND table_id BETWEEN 0 AND 10000