New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft: [IMP] base: Speed-up address_get method #165010
base: 15.0
Are you sure you want to change the base?
Conversation
0c6cb23
to
9338a6a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of suggestions, in case you haven't considered them yet.
9338a6a
to
f447f2a
Compare
Hello @moylop260 , Thank you for your suggestion. AFAIK, there are two main 'issues' with your solution:
We should know why fetching Note that reading a One2many should also be faster in 17.0. We can investigate further if this is a bottleneck for you (and perhaps after backporting the mentioned PR). |
Hi @ryv-odoo Thank you for reply!
I agree, I share the py-spy result: odoo original py-spyodoo fix PR-105350 (without pre-populate cache)The biggest bar is related to line:
I can work to get an unittest to consider this case But I'm not sure to understand the case of use Could you help me to give me more details on where the result could be different using this fix, please? |
Hi,
Here you go. I am not sure if it is possible to reproduce by hand, but nothing prevents it. def test_multiple_level_address_get(self):
Partner = self.env['res.partner']
main_p = Partner.create({
'name': 'main',
'type': 'contact',
})
child_p = Partner.create({
'name': 'child',
'type': 'private',
'parent_id': main_p.id,
})
grandchild_p = Partner.create({
'name': 'grandchild',
'type': 'invoice',
'parent_id': child_p.id,
})
self.assertEqual(main_p.address_get(['invoice'])['invoice'], grandchild_p.id) We can see some interesting things in your pyflam:
Have a nice day |
f447f2a
to
d4dfc17
Compare
I just did a new commit with your findings If I understood well we need to get all the descendants and get the address type to match with the child but prioritizing the first level (less depth) So, getting a recursive-query to get all them and ordered by depth it will get the same result but faster The query generated is: WITH RECURSIVE descendants AS (
...
)
SELECT DISTINCT ON (type)
type, id
FROM descendants
ORDER BY type, path... And it is passing your unittesting well! |
@moylop260 what do you think about using the operator |
5413452
to
bd0969a
Compare
d796401
to
bb6b511
Compare
cc7e72e
to
956d3c9
Compare
cf6cd1d
to
d38805b
Compare
partners with many children need to visit all the children to check if the address match with the prefered one But it is not needed if you know the prefered address doesn't match Searching the children directly with search method it is faster
The csv file was used with the old version of odoo in order to get the results in order to compare with new results of latest changes to partner.address_get method
d38805b
to
922fa04
Compare
partners with many children need to visit all the children to check if the address match with the prefered one But it is not needed if you know the prefered address doesn't match Searching the children directly with search method it is faster
You can test using the following script
(or a little more complex but faster using many threads https://gist.github.com/moylop260/c4ae432f2f8ae72b94fcc3bb1a3dc419)
Fast-tracking creating the database I uploaded a backup with the records created:
Using original code the profiler shows:
Notice it spend 1806.75s and max number of hits 1111102
Using this improvement the profiler shows:
Notice it spends 0.10s and max number of hits 5
It means, this fix is 17.5k times faster for this case
It is running extra search instead of using cache for small partner but even it is faster with small partners
Using a partner with only 3 children:
(I tried to improve even more using
read_group
but it is returning all the children and aggregator methods are limited in the odoo API I mean, the odoo API is not supporting the aggregatorFIRST(id order by %s) % self._name
):odoo/odoo/models.py
Lines 285 to 288 in d6785a1
Another way is to use directly SQL, but I prefer using
search(..., limit=1)
instead since it is using a max of 2 address so not a big deal here using itIt is improving many process of odoo where this method is called:
odoo/odoo/addons/base/models/res_company.py
Line 130 in 60d6a40
odoo/addons/website_sale/models/website.py
Line 218 in 60d6a40
odoo/addons/sale/models/account_move.py
Line 50 in 60d6a40
odoo/addons/sale/models/sale_order.py
Line 445 in 60d6a40
odoo/addons/sale/models/sale_order.py
Line 552 in 60d6a40
odoo/addons/hr/models/hr_employee_base.py
Line 131 in 60d6a40
odoo/addons/pos_sale/models/pos_order.py
Line 34 in 60d6a40
odoo/addons/hr_recruitment/models/hr_recruitment.py
Line 499 in 60d6a40
odoo/addons/hr_recruitment/models/hr_recruitment.py
Line 513 in 60d6a40
odoo/addons/account/models/account_move.py
Line 2711 in 60d6a40
odoo/addons/point_of_sale/models/pos_order.py
Line 604 in 60d6a40
odoo/addons/repair/models/repair.py
Line 128 in 60d6a40
odoo/addons/repair/models/repair.py
Line 195 in 60d6a40
odoo/addons/membership/models/partner.py
Line 103 in 60d6a40
odoo/addons/event/models/event_registration.py
Line 152 in 60d6a40
odoo/addons/purchase/models/purchase.py
Line 596 in 60d6a40