From fd24ac100eb59e9341e57a47e341b0cbfbf6cea9 Mon Sep 17 00:00:00 2001 From: Raphael Collet <rco@odoo.com> Date: Thu, 9 Jan 2020 10:48:26 +0000 Subject: [PATCH] [FIX] expression: performance of search on one2many fields We optimize the search on domains like `[('line_ids', 'in', ids)]`. The condition is rewritten `('id', 'in', ids1)` where `ids1` is the result of SELECT <many2one_field> FROM <comodel_table> WHERE id IN <ids> The issue is that the latter potentially returns many duplicate values. The fix consists in having as few duplicates as possible in `ids1`. Note that domains like `[('line_ids.foo', '=', 42)]` implicitly benefit from the optimization, as they are rewritten as the one above with ids = comodel.search([('foo', '=', 42)]).ids closes odoo/odoo#43566 X-original-commit: a13c05fa5df9c98504e8e1cdb09d8d4a8d13ea91 Signed-off-by: Raphael Collet (rco) <rco@openerp.com> --- odoo/osv/expression.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/odoo/osv/expression.py b/odoo/osv/expression.py index 35c66c7f9230..927c7fa739c0 100644 --- a/odoo/osv/expression.py +++ b/odoo/osv/expression.py @@ -441,14 +441,14 @@ def select_from_where(cr, select_field, from_table, where_field, where_ids, wher res = [] if where_ids: if where_operator in ['<', '>', '>=', '<=']: - cr.execute('SELECT "%s" FROM "%s" WHERE "%s" %s %%s' % \ + cr.execute('SELECT DISTINCT "%s" FROM "%s" WHERE "%s" %s %%s' % \ (select_field, from_table, where_field, where_operator), (where_ids[0],)) # TODO shouldn't this be min/max(where_ids) ? res = [r[0] for r in cr.fetchall()] else: # TODO where_operator is supposed to be 'in'? It is called with child_of... for i in range(0, len(where_ids), cr.IN_MAX): subids = where_ids[i:i + cr.IN_MAX] - cr.execute('SELECT "%s" FROM "%s" WHERE "%s" IN %%s' % \ + cr.execute('SELECT DISTINCT "%s" FROM "%s" WHERE "%s" IN %%s' % \ (select_field, from_table, where_field), (tuple(subids),)) res.extend([r[0] for r in cr.fetchall()]) return res -- GitLab