Skip to content
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

Fix performance problem when searching for groups in the groupfolder app #32201

Closed
wants to merge 12 commits into from

Conversation

CarlSchwan
Copy link
Member

@CarlSchwan CarlSchwan commented Apr 28, 2022

The scope of this PR ended up a bit bigger than initially thought.

  • Add a method in group backends to search user for userId/display name and directly return User object (lazy with display name possibly preloaded). This should be nicer in terms of performance as we don't need to separately load the display names (e.g. when searching in the ui)
  • Add a lot of type hinting + doc in IGroup/Group
  • Remove the unused Backend since it was unused
  • Fix various psalm issues and avoid calling the deprecated method implementsActions

This target NC 25, but we might do a partial backport to NC 24 and earlier (the optimization)

@CarlSchwan CarlSchwan self-assigned this Apr 28, 2022
@CarlSchwan CarlSchwan marked this pull request as draft April 28, 2022 06:45
@CarlSchwan CarlSchwan requested a review from come-nc May 2, 2022 15:58
apps/user_ldap/lib/GroupPluginManager.php Outdated Show resolved Hide resolved
apps/user_ldap/lib/GroupPluginManager.php Show resolved Hide resolved
apps/user_ldap/lib/Group_LDAP.php Outdated Show resolved Hide resolved
apps/user_ldap/lib/Group_LDAP.php Show resolved Hide resolved
apps/user_ldap/lib/Group_Proxy.php Outdated Show resolved Hide resolved
lib/private/Diagnostics/QueryLogger.php Outdated Show resolved Hide resolved
lib/private/Group/Database.php Outdated Show resolved Hide resolved
lib/private/Group/Group.php Show resolved Hide resolved
@CarlSchwan CarlSchwan force-pushed the fix/performance-search-groupfolder branch from 121e074 to b8a8de4 Compare May 3, 2022 12:23
@CarlSchwan CarlSchwan marked this pull request as ready for review May 3, 2022 12:46
@CarlSchwan CarlSchwan changed the title WIP: Fix performance problem when searching for users in the groupfolder app Fix performance problem when searching for users in the groupfolder app May 3, 2022
Copy link
Member

@blizzz blizzz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All nice, with the one downside that the search now happens on terms of the group backend. Group backends able to contain users of mixed user backends thus do not utilize the search methods of the user backends. For example, when normally you can find "Jeanne Doe" of LDAP by her employee number 123456, you cannot achieve the same when search for her in the local group. The sad thing of course is that the owning user backend does not know about this relationship, so searching there will would also be painfully slow (likely better than now, but still).

With that in mind, this approach may be acceptable with this known limitation (that should be documented somewhere). Additional the slower search can be offered still and enabled via config option – and as opt-in. Searching for display name* and email is the default case after all.

*also there might be different results

apps/user_ldap/lib/GroupPluginManager.php Outdated Show resolved Hide resolved
apps/user_ldap/lib/Group_LDAP.php Show resolved Hide resolved
apps/user_ldap/lib/Group_Proxy.php Show resolved Hide resolved
apps/user_ldap/lib/Group_Proxy.php Outdated Show resolved Hide resolved
lib/private/Group/Manager.php Show resolved Hide resolved
@CarlSchwan CarlSchwan force-pushed the fix/performance-search-groupfolder branch from 21fdf4c to 0f3f112 Compare May 5, 2022 23:07
@CarlSchwan
Copy link
Member Author

All nice, with the one downside that the search now happens on terms of the group backend. Group backends able to contain users of mixed user backends thus do not utilize the search methods of the user backends. For example, when normally you can find "Jeanne Doe" of LDAP by her employee number 123456, you cannot achieve the same when search for her in the local group. The sad thing of course is that the owning user backend does not know about this relationship, so searching there will would also be painfully slow (likely better than now, but still).

According to the code, the search happens like this with this patch:

  • OC\Group\Manager::displayNamesInGroup
  • OC\Group\Group::searchUsers - Call searchInGroup for each group backend
    • Database backend: will look for any displayname+userId with the corresponding gid
    • LDAP backend: merge the results of getUsersInPrimaryGroup, getUsersInGidNumber and _groupMembers (recursive)

Before:

  • OC\Group\Manager::displayNamesInGroup
  • OC\User\UserManager::searchDisplayName with an high limit
    • Database backend: will look for any displayname+userId discarding the gid information
    • LDAP backend: call getUsers that then do an LDAP query with getFilterPartForUserSearch
  • In the resulting results, look if they are part of the group
    • Database backend: a db query for each user matching the search filtr
    • LDAP backend: search if the user is in the primary group and if not do __groupMembers (recursive) and check if the user is found in the group members returned

So to me, this seems equivalent just faster and cleaner, unless I obliviously missed something. Maybe we should do a call on Monday to discuss this if you have time?

@CarlSchwan CarlSchwan force-pushed the fix/performance-search-groupfolder branch 3 times, most recently from 01190a9 to f57e809 Compare May 13, 2022 14:02
@CarlSchwan
Copy link
Member Author

ping :)

@CarlSchwan
Copy link
Member Author

friendly ping :)

@CarlSchwan CarlSchwan force-pushed the fix/performance-search-groupfolder branch from f57e809 to 4a60577 Compare May 30, 2022 11:21
@PVince81 PVince81 requested a review from artonge June 3, 2022 13:16
@PVince81
Copy link
Member

/rebase

@nextcloud-command nextcloud-command force-pushed the fix/performance-search-groupfolder branch from 4716930 to 32cabdd Compare June 10, 2022 16:40
* @param string $id
* @return Access
*/
abstract public function getLDAPAccess($id);
abstract public function getLDAPAccess($gid);

Check notice

Code scanning / Psalm

MissingParamType

Parameter $gid has no provided type
Before we were fetching 1000 users and then filter them by name

Signed-off-by: Carl Schwan <carl@carlschwan.eu>
Signed-off-by: Carl Schwan <carl@carlschwan.eu>
Signed-off-by: Carl Schwan <carl@carlschwan.eu>
@CarlSchwan CarlSchwan force-pushed the fix/performance-search-groupfolder branch from 32cabdd to 6e00901 Compare June 13, 2022 15:06
@CarlSchwan CarlSchwan changed the title Fix performance problem when searching for users in the groupfolder app Fix performance problem when searching for groups in the groupfolder app Jun 13, 2022
lib/private/Group/Database.php Fixed Show fixed Hide fixed
lib/private/Group/Manager.php Fixed Show fixed Hide fixed
lib/private/Group/Manager.php Fixed Show fixed Hide fixed
lib/public/Group/Backend/ABackend.php Fixed Show fixed Hide fixed
lib/public/Group/Backend/ABackend.php Fixed Show fixed Hide fixed
lib/public/Group/Backend/ABackend.php Fixed Show fixed Hide fixed
@CarlSchwan
Copy link
Member Author

@blizzz I reverted the changes for the search and found out instead other areas where we could improve the perf by quite a bit:

  • When searching with the database group backend, cache the displayname
  • Implement a batch groupExists and getGroupDetails methods (with a fallback when not implemented).

In total, with 1100 LDAP groups, these changes reduce the SQL query count from 1125 to 13. The LDAP query count is still very high (>6000) but I have a PR in groupfolder to reduce it to 30.

I'll try to split the change into multiple self-contained PRs to make it easier to review :)

groupDetails method

Signed-off-by: Carl Schwan <carl@carlschwan.eu>
@CarlSchwan
Copy link
Member Author

First split #32866

@skjnldsv
Copy link
Member

As there is no feedback since a while I will close this ticket.
If you will decide to work on this feature again and if it hasn't been fixed or implemented already, feel free to re-open and solve the various conflicts.

@skjnldsv skjnldsv closed this Feb 27, 2024
@skjnldsv skjnldsv added 2. developing Work in progress and removed 3. to review Waiting for reviews labels Feb 27, 2024
@skjnldsv skjnldsv deleted the fix/performance-search-groupfolder branch February 27, 2024 17:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants