DISTINCT对巨大的不确定性

时间:2017-05-23 09:00:59

标签: postgresql distinct common-table-expression recursive-query

我有一个带有intarrayfeature_value_ids的物化视图(~100k行)。我想要的是根据物化视图上的一些条件选择该列中的所有唯一ID

此查询运行正常,aprox。 30毫秒,给出~1密耳行:

SELECT unnest(feature_value_ids) FROM dematerialized_products               
WHERE is_private = 'f' AND product_category_ids && ARRAY [38]

但是,如果我添加DISTINCT,查询将下降到~400ms,给出~5k行

SELECT DISTINCT unnest(feature_value_ids) FROM dematerialized_products               
WHERE is_private = 'f' AND product_category_ids && ARRAY [38]

我尝试做一个没有运气的递归查询(~35s),像这样:

WITH RECURSIVE t AS (
  (SELECT min(value_id) AS value_id FROM z)
  UNION ALL
  SELECT (SELECT min(value_id) FROM z WHERE value_id > t.value_id) AS value_id
  FROM t
      WHERE t.value_id IS NOT NULL
), z as (
    SELECT unnest(feature_value_ids) as value_id
    FROM dematerialized_products a
    WHERE is_private = 'f' AND product_category_ids && ARRAY [38]
)

SELECT * FROM t WHERE t.value_id IS NOT NULL

我想这是因为z每次递归查询都会进行评估

2 个答案:

答案 0 :(得分:1)

您没有显示执行计划,但显然需要花时间对值进行排序以消除双倍。

如果EXPLAIN (ANALYZE)显示使用临时文件执行排序,则可以通过引发work_mem来提高性能,以便可以在内存中执行排序。

DISTINCT您仍会遇到性能损失。

答案 1 :(得分:1)

数组中featured_value_id数组值是唯一的吗?如果不是这样,如果你给计划者一个小手,让它们变得独特吗?:

select distinct c.id
from
    dematerialized_products
    cross join lateral
    (
        select distinct id
        from unnest(feature_value_ids) u (id)
    ) c