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

Posted

技术标签:

【中文标题】在 Oracle 中运行速度极慢的 Postgres 查询【英文标题】:Extremely slow Postgres query that runs fast in Oracle 【发布时间】:2020-11-11 16:50:46 【问题描述】:

因此,在对 Oracle 有一些经验后,我才开始在 PostgreSQL 中工作,并且我有这个查询,在 Oracle 中返回 200 毫秒,在 Postgres 中返回 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 是一个视图,我还指出,如果我用一个也有 product_type_id 的表替换该视图,那么它也可以快速运行。我尝试以 100 种不同的形式使用 CTEsubselects,但是当我在 where 子句中使用 product.product_type_id 时,它的运行速度非常慢,我看不到我错过了什么。提前致谢 :) 附言是的,我在两个数据库中都有完全相同的数据和索引

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)
    );

【问题讨论】:

请注意,子查询中的distinct 完全没用。 Oracle 可能会优化它,但我认为 Postgres 不会 edit您的问题并添加使用explain (analyze, buffers, format text)生成的execution plan(不是只是一个“简单”解释)为formatted text,并确保保留计划的缩进。粘贴文本,然后将``` 放在计划前一行和计划后一行。还请包括所有索引的完整 create index 语句。 【参考方案1】:

由于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');

【讨论】:

【参考方案2】:

你能试试这个变种吗:

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'

【讨论】:

谢谢,它现在运行得很快!你能解释一下为什么它在第一种形式中很慢吗? 好吧,如果不在您的环境中运行代码,很难判断,但从我的实践中,我看到很多情况,当 SQL 引擎(SQL Server、PosgreSQL、Oracle)没有构建正确的如果查询太复杂,则计划。所以,我只是尽量简化它。

以上是关于在 Oracle 中运行速度极慢的 Postgres 查询的主要内容,如果未能解决你的问题,请参考以下文章

API 设计:我可以阻止用户进行极慢的查询吗?

极慢的 Wordpress WooCommerce 网站(在管理面板和最终用户中)

ffmpeg.js 在 iOS cordova 中运行速度极慢(但在 iOS safari 中运行良好?)

Linux(Centos)下jdbc连接oracle速度超慢的问题

执行极慢的 SELECT

Python语言 SQLite怎么用内存数据库解决插入数据时速度慢的问题?