From 9b42ab531d4ddfa4fd8a41af137e59ffa6b5b7bf Mon Sep 17 00:00:00 2001 From: "Benjamin Hanquin (beha)" Date: Tue, 5 Sep 2023 17:31:36 +0200 Subject: [PATCH] [PERF] spreadsheet_account: optimize fetch_debit_credit SQL query MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue: Displaying the data on the dashboard accounting can take up to 1 minute Analysis: The spreadsheet_fetch_debit_credit function needs a domain in order to compute the formulas. The domain being set in `_build_spreadsheet_formula_domain` use a like search for account_account.code on account_move_line which is a big table. Thus it does not scale well. There is also a unnecessary complexity on adding an "OR expression" on each one of the account_id code searched for. Solution: It can be optimized by searching for the full exhaustive (like in SQL) codes in account.accoun since it has way less records and thus more scalable. And then use an exact condition (=) which is faster than a like search. Also adding more readable while adding the balance_domain and pnl domain only once in the whole query. Benchmark: | Before PR | After PR | |:----------:|:---------:| | 8s 51 ms | 42 ms code search + 42 ms full query | Related ticket: opw-3328144 Version affected: 16.0 and above closes odoo/odoo#134889 X-original-commit: a707f8345cec8f404077b184f4b0339932c10892 Signed-off-by: Lucas Lefèvre (lul) --- addons/spreadsheet_account/models/account.py | 13 +++++++------ .../spreadsheet_account/tests/test_debit_credit.py | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/addons/spreadsheet_account/models/account.py b/addons/spreadsheet_account/models/account.py index cbabac7779a..e5e88de87c3 100644 --- a/addons/spreadsheet_account/models/account.py +++ b/addons/spreadsheet_account/models/account.py @@ -58,16 +58,17 @@ class AccountMove(models.Model): ("date", ">=", start), ("date", "<=", end), ] + # It is more optimized to (like) search for code directly in account.account than in account_move_line code_domain = expression.OR( [ - expression.AND([ - [("account_id.code", "=like", f"{code}%")], - expression.OR([balance_domain, pnl_domain]), - ]) - for code in codes + ("code", "=like", f"{code}%"), ] + for code in codes ) - domain = expression.AND([code_domain, [("company_id", "=", company_id)]]) + account_ids = self.env["account.account"].search(code_domain).ids + code_domain = [("account_id", "in", account_ids)] + period_domain = expression.OR([balance_domain, pnl_domain]) + domain = expression.AND([code_domain, period_domain, [("company_id", "=", company_id)]]) if formula_params["include_unposted"]: domain = expression.AND( [domain, [("move_id.state", "!=", "cancel")]] diff --git a/addons/spreadsheet_account/tests/test_debit_credit.py b/addons/spreadsheet_account/tests/test_debit_credit.py index fa8bdeece20..b2a2f59e35f 100644 --- a/addons/spreadsheet_account/tests/test_debit_credit.py +++ b/addons/spreadsheet_account/tests/test_debit_credit.py @@ -919,7 +919,7 @@ class SpreadsheetAccountingFunctionsTest(AccountTestInvoicingCommon): "&", "&", "&", - ("account_id.code", "=like", "sp1234566%"), + ("account_id", "in", [self.account_revenue_c1.id]), "|", "&", ("account_id.include_initial_balance", "=", True),