[IMP] website: perf - reduce SQL queries for the website menu
Render page flow:
- Search website.page in _serve_page for requested URL
- Check if the page is visible with `is_visible`
- `is_visible` will get the `ir.ui.view` of the page
Note that this is not 'cachable' as being visible depends of now() for the
publishing date
- Render layout which is getting the website menus
Note that this can't be cached either as a menu visibility might also
depends of it's website.page visibility which depends of now()
- Checking menus `is_visible` fetch the menus pages and those pages views.
Before this commit, every level of menu hierarchy would add 2 queries.
This can be avoided by prefetching everything in once during the dispatch if we
know we will render the website menu.
In such a case, read `is_visible` on every website menus will fetch every
pages, views and menus in the lowest SQL queries possible, eg one query for
every table.
For a 3 level menus, requests goes from 20 to 12 to load a untracked page.
task-2211013
This commit is contained in:
@@ -143,7 +143,8 @@ class Website(models.Model):
|
||||
# don't add child menu if parent is forbidden
|
||||
if menu.parent_id and menu.parent_id in menus:
|
||||
menu.parent_id._cache['child_id'] += (menu.id,)
|
||||
|
||||
# prefetch every website.page and ir.ui.view at once
|
||||
menus.mapped('is_visible')
|
||||
website.menu_id = menus and menus.filtered(lambda m: not m.parent_id)[0].id or False
|
||||
|
||||
# self.env.uid for ir.rule groups on menu
|
||||
|
||||
@@ -113,7 +113,7 @@ class TestWebsitePerformance(UtilPerf):
|
||||
menu_bb.parent_id = menu_b
|
||||
menu_aa.parent_id = menu_a
|
||||
|
||||
self.assertEqual(self._get_url_hot_query(self.page.url), 22)
|
||||
self.assertEqual(self._get_url_hot_query(self.page.url), 14)
|
||||
|
||||
def test_50_perf_sql_web_content(self):
|
||||
# assets route /web/content/..
|
||||
|
||||
Reference in New Issue
Block a user