在 Oracle 中运行速度极慢的 Postgres 查询

Extremely slow Postgres query that runs fast in Oracle

所以我在使用 Oracle 获得一些经验后才开始使用 PostgreSQL,我有这个查询,在 Oracle returns 中需要 200 毫秒,在 Postgres returns 中需要 1.40 分钟。罪魁祸首似乎是

AND product_cost_view.product_type_id = product.product_type_id

当我删除这部分或使用某些 ID 硬编码 product_cost_view.product_type_id 时,它运行得很快。解释计划似乎没有提供和洞察力,它只是说 INDEX SCAN ON TABLE product TOTAL COST 776403 1913 ROWS

是的,product_cost_view 是一个视图,我还指出,如果我用 table 替换那个视图,该视图也有 product_type_id,那么它也可以快速工作。我尝试以 100 种不同的形式使用 CTEsubselects,但是当我在带有该视图的 where 子句中使用 product.product_type_id 时,它的工作速度非常慢,我看不到我错过了什么。提前致谢 :) P.S。是的,我在两个数据库中有完全相同的数据和索引

SELECT COUNT(*)
FROM product
WHERE user_id = 1000000
  AND (product_id IN (SELECT DISTINCT product_id
                        FROM product_cost_view
                        WHERE user_id = 1000000
                          AND cost_type = 'X'
                          AND product_cost_view.product_type_id = product.product_type_id)
    );

你能试试这个变体吗:

SELECT COUNT(DISTINCT P.product_id)
FROM product P
INNER JOIN product_cost_view PC
    ON P.product_id = PC.product_id
    AND P.user_id = PC.user_id
    AND P.product_type_id = PC.product_type_id
WHERE P.user_id = 1000000
    AND PC.cost_type = 'X'

由于 DISTINCT,PostgreSQL 无法将子查询展平为连接,因此您是 运行 在 product 中找到的每一行的子查询。

没有看到执行计划很难说,但这应该更快:

SELECT COUNT(*)
FROM product AS p
WHERE p.user_id = 1000000
  AND EXISTS (SELECT 1 FROM product_cost_view AS pc
              WHERE pc.product_type_id = p.product_type_id
                AND pc.product_id = p.product_id
                AND pc.user_id = 1000000
                AND pc.cost_type = 'X');