From 875244b08eb95f653d9c2ada699105cbec859521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20=28avd=29?= Date: Wed, 24 Aug 2022 13:33:38 +0000 Subject: [PATCH] [FIX] res_currency: add order by to _select_companies_rates query MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PG12 introduced an optimization for CTEs that automatically inlines CTEs if they are only refered once in the parent query. Prior to that CTEs were always materialzed, meaning that PG created a sort of temp table on the fly to store the result of the CTE's evaluation. Whereas this leads to performance improvements in general, in the particular case of _select_companies_rates this inlining becomes a performance bottleneck. This is because while the currency_rate CTE is only refered once in both purchase_report and product_margin, the join condition (cr.date_end is null or cr.date_end > ...) requires evaluating the CTE's date_end subquery twice. This, combined with the fact that in PG12 the planner goes for a Nested Loop JOIN instead of a HASH Join in PG10 makes the performances of the whole query much worse in PG12 than in PG10. Adding MATERIALIZED before the CTE definition forces PG to evaluate the subquery first using its own plan. This removes the need to rescan the subquery each time the Merge JOIN filter has to be applied, which is a good strategy in this specific situation. Examples of query timings change before and after PR: Number of POs | Before PR | After PR 2000 | 7s | 345ms 7000 | 23s | 1.1s opw-2930578 closes odoo/odoo#106100 X-original-commit: c4d841e81904745a24669e1a05f0d21ca7f2c85d Signed-off-by: Raphael Collet Signed-off-by: Van Delft Aurélien (avd) --- addons/product_margin/models/product_product.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/product_margin/models/product_product.py b/addons/product_margin/models/product_product.py index 06c7dd37c46..6fe2321eddb 100644 --- a/addons/product_margin/models/product_product.py +++ b/addons/product_margin/models/product_product.py @@ -120,7 +120,7 @@ class ProductProduct(models.Model): self.env['account.move'].flush_model(['state', 'payment_state', 'move_type', 'invoice_date', 'company_id']) self.env['product.template'].flush_model(['list_price']) sqlstr = """ - WITH currency_rate AS ({}) + WITH currency_rate AS MATERIALIZED ({}) SELECT l.product_id as product_id, SUM(