Hi
we have a site with loads of entities and > 43.000 entities are loaded by entity_load() in og_menu_node_prepare().
Yes this is a very large number but we can't get around. So I try to figure why the entities are loaded at all and if we really need to do this.
The exact line is 642
// Using the handler allows us to get user options from OG without
// running through all the user's groups.
$ids = entityreference_get_selection_handler($field, $instance)->getReferencableEntities();
I can't figure why you load all possible targets here as I don't know your module very well. But with this it will simply not scale. And I believe this is not a problem in configuration.
It seems that you only use the id of the entity so maybe this can be done by some EFQ and not by getReferencableEntities() as this function loads the full entity?
Can we please chat in IRC or do a hangout what we could to here to set some limits?
Comments
Comment #1
rv0 CreditAttribution: rv0 commentedActually, this is the exact method that organic groups is doing it.. I think it gets called multiple times (even in og_node_access)
The only way to know which groups can be selected is by asking the entity reference selection handler (as there can be completely custom implemented behavior there).
I dont know if there's a better way
> 43.000 is indeed a bit crazy, dont you have a way to limit the entities available for selection, or write a custom selection handler?
If those 43000 entities come with the same number of menus, OG Menu's front end will crash too.
Comment #2
Kars-T CreditAttribution: Kars-T commentedI believe you are referring to line 525 in og_node_access()?
In this case it is a wrong use of the entity reference API. The return values is not used at all and all entities would be loaded. I will add an issue to og that they use
\EntityReference_SelectionHandler_Generic::countReferencableEntities()
here and avoid the problem.
For og_menu there seem to be more problems with scalability. It seems you are only needing the entity ids here. And than you loop them in og_menu_get_group_menus(). That would be > 43.000 queries than. Not good ;)
We have to find a way to circumvent all this and that og_menu can scale and shine! :)
Comment #3
Frank Ralf CreditAttribution: Frank Ralf commented#1477868: OG Scalability says OG is capable of handling +10.000 groups, though.
Comment #4
tstoecklerRight I looked at og_menu_get_group_menus() and that should be fixed as well, maybe in a separate issue, I don't know.
For this issue, I think we would need some upstream changes in OG, but in terms of actual code this should be very easy to do.
If you look into EntityReference_SelectionHandler_Generic::countReferencableEntities() it does:
So there could be a EntityReference_SelectionHandler_Generic::getReferencableEntityIds():
I guess we should open an issue titled "Introduce a EntityReference_SelectionHandler_Generic::getReferencableEntityIds()" in OG?!
Edit: Copy-paste failure
Edit2: Again...
Comment #5
rv0 CreditAttribution: rv0 commentedActually, this originates in entityreference module., not in OG
In any case, 43000 menus will make the front end crash for sure.. The menu handling would need to be ajaxified
Comment #6
Kars-T CreditAttribution: Kars-T commented@tstoeckler I believe the method is inside EntityReference and not og. So EntityReference should get the method to get the ids.
@rv0 Maybe paged lists or ajax yes. But imho this should be done in any case so lets see what we can do together :)
Comment #7
Frank Ralf CreditAttribution: Frank Ralf commented@tstoeckler
JFTR:
Comment #8
Kars-T CreditAttribution: Kars-T commentedResetting the a title of this issue to a more "meta" title so we can coordinate the scalability issues from this issue.
Comment #9
tstoecklerFiled #2059825: Majorly improve the performance of og_menu_get_group_menus() for #2/#4.
Comment #10
tstoecklerFound #2063149: og_menu_node_prepare() does unneccessary heavy-lifting in some cases
I still don't fundamentally grok, why og_menu_node_prepare() does what it does, but this at least avoids the heavy processing in some cases.
Comment #11
rv0 CreditAttribution: rv0 commentedJust had hard time debugging an older 2.x site with 1000 menus and a 4 big main menus. node/add page load time was 100 seconds
Eventually I could fix it only because the site doesn't allow manual selection of group audience (prepopulated from url).
So instead of loading all menu trees, I adapted the code to only load it for the groups provided in url(new node) or group audience fields (existing node).
However, this further raises the question if we should replace the menu select with an ajaxified version that only loads what is needed
Comment #12
anthonys CreditAttribution: anthonys commentedI think the AJAX version is what the menuperformance module does. Perhaps integrating with that would be a good idea.
Comment #13
rv0 CreditAttribution: rv0 at Coworks.be commentedI've been looking into this "getReferencableEntities()" part. It causes an entity_load on all items indeed.
But... If I replace it by:
to just get the id's, it results in an equal memory footprint but even slower page rendering time. This is because the entities get loaded individually anyway further down the road (e.g.: og_user_access => og_is_group), where those individual loads come from cache in the current codebase.
Comment #14
rv0 CreditAttribution: rv0 at Coworks.be commentedadded note to project page:
Comment #15
anthonys CreditAttribution: anthonys commentedThanks - that looks useful
Comment #16
dalinSince this appears to be a meta issue, you all might be interested in #2881709