[FIX] product: speed up _name_search

If `_name_search` is called with `limit=None` it could take time in the loop
because `_name_search` for `product.product` has `limit=100`, i.e. it could be
100 iterations to scan 10 K products. To solve this problem, call `_name_search`
with `limit=None` to get all product variants at once.

As an example, the problem is reproduced on using menu `Manufacturing > Products
> Bills of Materials`, which makes following search query:

```
["|", ["code", "ilike", "XXX"], ["product_tmpl_id", "ilike", "XXX"]]
```

for which ORM calls `_name_search`:

https://github.com/odoo/odoo/blame/9b23864027bc24032993833f213395cb45fe86bb/odoo/osv/expression.py#L863

In a customer database, this speeds up the query from 70 seconds to 3,5 seconds.

---

opw-2631012

closes odoo/odoo#77601

X-original-commit: 038816725a988a0ada3d6f8518a436ea46a81eba
Signed-off-by: Ivan Yelizariev // IEL <yelizariev@users.noreply.github.com>
This commit is contained in:
Ivan Yelizariev
2021-10-01 12:41:07 +00:00
parent de7e0c6b06
commit ef90c22efd
+4 -1
View File
@@ -540,7 +540,10 @@ class ProductTemplate(models.Model):
while True:
domain = templates and [('product_tmpl_id', 'not in', templates.ids)] or []
args = args if args is not None else []
products_ids = Product._name_search(name, args+domain, operator=operator, name_get_uid=name_get_uid)
# Product._name_search has default value limit=100
# So, we either use that value or override it to None to fetch all products at once
kwargs = {} if limit else {'limit': None}
products_ids = Product._name_search(name, args+domain, operator=operator, name_get_uid=name_get_uid, **kwargs)
products = Product.browse(products_ids)
new_templates = products.mapped('product_tmpl_id')
if new_templates & templates: