From f89d7bbf8c6b55f59b9dcdc995f47749e4f02ab1 Mon Sep 17 00:00:00 2001 From: wan Date: Wed, 23 Sep 2020 12:26:18 +0000 Subject: [PATCH] [FIX] core: prefetching of x2many lines in snapshot.diff() The prefetching optimization was simply broken for x2many lines in the snapshot method `diff()`. Indeed, iterating on `line._prefetch_ids` actually returns nothing, because this iterable object relies on the value in cache of the x2many field, and the cache has been invalidated before calling `diff()`. In order to re-enable prefetching, we simply populate the cache of x2many fields before looping on the lines. Some testing with `account.move` and the relation `invoice_line_ids`: For 335 invoice lines, changing the value of a field in the invoice lines took about 1.9s with 1415 queries. It now takes about 1.1s and 82 queries. closes odoo/odoo#58687 X-original-commit: 5bd7ddd0850e56fbbae52b4478970331f9db1589 Signed-off-by: Raphael Collet (rco) Co-authored-by: Raphael Collet --- odoo/models.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/odoo/models.py b/odoo/models.py index 936b99633fc..2d57c223e99 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -6023,6 +6023,14 @@ Fields: else: # x2many fields: serialize value as commands result[name] = commands = [(5,)] + # The purpose of the following line is to enable the prefetching. + # In the loop below, line._prefetch_ids actually depends on the + # value of record[name] in cache (see prefetch_ids on x2many + # fields). But the cache has been invalidated before calling + # diff(), therefore evaluating line._prefetch_ids with an empty + # cache simply returns nothing, which discards the prefetching + # optimization! + record[name] for line_snapshot in self[name]: line = line_snapshot[''] line = line._origin or line