在 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 种不同的形式使用 CTE
和 subselects
,但是当我在 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 查询的主要内容,如果未能解决你的问题,请参考以下文章
极慢的 Wordpress WooCommerce 网站(在管理面板和最终用户中)
ffmpeg.js 在 iOS cordova 中运行速度极慢(但在 iOS safari 中运行良好?)