【问题标题】:DISTINCT over huge unnest与巨大的 unnest 不同
【发布时间】:2017-05-23 09:00:58
【问题描述】:

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

此查询运行正常,大约。 30 毫秒,大约 1 百万行:

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

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

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

我尝试在没有运气的情况下进行递归查询(〜 35 秒),如下所示:

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 每次递归查询都会进行评估

【问题讨论】:

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


    【解决方案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
    

    【讨论】:

      【解决方案2】:

      您没有显示执行计划,但显然时间花在了对值进行排序以消除双精度。

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

      DISTINCT 的性能仍然会受到影响。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-02-01
        • 1970-01-01
        • 2016-03-28
        • 2020-02-08
        • 1970-01-01
        • 2011-05-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多