We have run into a little performance issue in CMS v.10.10.1 and Commerce v11.2.0.
For some reason we get periods with a very high miss rate for the cache, if it is caused by an import or just premature eviction because of some other reason we don't know yet.
During these periods we have noticed that our menu construction creates a lot of database traffic specifically our calls to IContentLoader.GetChildren(contentReference), which doesn't just load all the node children from the database but also all the entry children(for some nodes this is over 3k)!
Looking into the DefaultContentLoader and sub-implementations it appears that it boils down to ContentProvider.TryGetChildren calling CatalogContentProvider.LoadChildrenReferencesAndTypes without supplying the type, which since it doesn't know what type we are asking for loads both nodes and entries.
Does anyone know if this have been addressed in any future version?
Foolishly i had thought that supplying a content type T would result in a query for what content type id T has (cached of course) and that id would be used as a parameter for the database calls to avoid fetching all content regardless of type. Yes i know it only loads the content references and not the entire content, but still why doesn't it work like that?
There are several approaches to loading items. One of them is try to load many in one go - then cache it for later uses. Later calls will only filtered on the cached list.
Of course there are pros and cons for that. That would reduce the number of roundtrips - but can have cons as you point out.
No we don't have plan to change that. The change must be done in CMS side - we are just returning what they ask us to do.
If you can provide some more number (time, etc.) - it would make an argument to look into the issue.
The big performance hit is when we for some reason don't get hits in the cache, instead of retrieving only <10 nodes we get 3-9k entries as well, each sp call only takes <100 ms but there is a heck of a lot of them as the menu is rendered all the time. We are seeing daily bursts where the database is responding with 250 Mb/s
Seeing the big shopping holidays approaching this is very probably going to be a killer for us.
Shouldn't the menu is cached? We had some other customers having the same kind of problem, because they didn't cache the menu :)
One other alternative is to restructure the catalog so a node can only contain either entries or nodes.
I'm not saying the API is perfect and should not be changed - but I think it's quite hard to convince a change here - even if I want to. As I said that would requires changes from CMS Core and it's likely a breaking change, so even if we do it, it's not happening anytime soon.
By the look of things that wouldn't really be necessary at all.
Today you override LoadChildrenReferencesAndTypes in CatalogContentProvider, but you can also override the GetChildrenReferences<T> method there.
Both methods are declared in EPiServer.Core.ContentProvider, but by overriding the second one that is called earlier in the callstack you would have access to the Type of the IContent asked for and can optimize your queries with it.
(Yes I ended up tip-toeing through the code in this hierarchy yet again, in search for performance thieves. )
Cache the menu using the object cache (for anonymous users only) meanwhile?
Yepp we are doing that now and it mitigates the problem for the menu.
Not possible for my current investigation since it is an custom import tool. :)