Skip to content

perf(MemberRequest): Remove unused LEFT JOINs #1969

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

Merged
merged 1 commit into from
Jun 2, 2025

Conversation

provokateurin
Copy link
Member

I tested this with the Contacts app and there showing the members still works without these LEFT JOINs as the requested data is never used.
This drastically reduces the number of LEFT JOINs from 13 to just 3.

Before:

SELECT "c"."circle_id",
       "c"."member_id",
       "c"."single_id",
       "c"."user_id",
       "c"."instance",
       "c"."user_type",
       "c"."level",
       "c"."status",
       "c"."note",
       "c"."contact_id",
       "c"."cached_name",
       "c"."cached_update",
       "c"."contact_meta",
       "c"."joined",
       "c_g"."unique_id"               AS "c_g_unique_id",
       "c_g"."name"                    AS "c_g_name",
       "c_g"."display_name"            AS "c_g_display_name",
       "c_g"."sanitized_name"          AS "c_g_sanitized_name",
       "c_g"."source"                  AS "c_g_source",
       "c_g"."description"             AS "c_g_description",
       "c_g"."settings"                AS "c_g_settings",
       "c_g"."config"                  AS "c_g_config",
       "c_g"."contact_addressbook"     AS "c_g_contact_addressbook",
       "c_g"."contact_groupname"       AS "c_g_contact_groupname",
       "c_g"."creation"                AS "c_g_creation",
       "c_g_d"."circle_id"             AS "c_g_d_circle_id",
       "c_g_d"."member_id"             AS "c_g_d_member_id",
       "c_g_d"."single_id"             AS "c_g_d_single_id",
       "c_g_d"."user_id"               AS "c_g_d_user_id",
       "c_g_d"."instance"              AS "c_g_d_instance",
       "c_g_d"."user_type"             AS "c_g_d_user_type",
       "c_g_d"."level"                 AS "c_g_d_level",
       "c_g_d"."status"                AS "c_g_d_status",
       "c_g_d"."note"                  AS "c_g_d_note",
       "c_g_d"."contact_id"            AS "c_g_d_contact_id",
       "c_g_d"."cached_name"           AS "c_g_d_cached_name",
       "c_g_d"."cached_update"         AS "c_g_d_cached_update",
       "c_g_d"."contact_meta"          AS "c_g_d_contact_meta",
       "c_g_d"."joined"                AS "c_g_d_joined",
       "c_b"."unique_id"               AS "c_b_unique_id",
       "c_b"."name"                    AS "c_b_name",
       "c_b"."display_name"            AS "c_b_display_name",
       "c_b"."sanitized_name"          AS "c_b_sanitized_name",
       "c_b"."source"                  AS "c_b_source",
       "c_b"."description"             AS "c_b_description",
       "c_b"."settings"                AS "c_b_settings",
       "c_b"."config"                  AS "c_b_config",
       "c_b"."contact_addressbook"     AS "c_b_contact_addressbook",
       "c_b"."contact_groupname"       AS "c_b_contact_groupname",
       "c_b"."creation"                AS "c_b_creation",
       "c_b_i"."circle_id"             AS "c_b_i_circle_id",
       "c_b_i"."member_id"             AS "c_b_i_member_id",
       "c_b_i"."single_id"             AS "c_b_i_single_id",
       "c_b_i"."user_id"               AS "c_b_i_user_id",
       "c_b_i"."instance"              AS "c_b_i_instance",
       "c_b_i"."user_type"             AS "c_b_i_user_type",
       "c_b_i"."level"                 AS "c_b_i_level",
       "c_b_i"."status"                AS "c_b_i_status",
       "c_b_i"."note"                  AS "c_b_i_note",
       "c_b_i"."contact_id"            AS "c_b_i_contact_id",
       "c_b_i"."cached_name"           AS "c_b_i_cached_name",
       "c_b_i"."cached_update"         AS "c_b_i_cached_update",
       "c_b_i"."contact_meta"          AS "c_b_i_contact_meta",
       "c_b_i"."joined"                AS "c_b_i_joined",
       "c_b_h"."circle_id"             AS "c_b_h_circle_id",
       "c_b_h"."member_id"             AS "c_b_h_member_id",
       "c_b_h"."single_id"             AS "c_b_h_single_id",
       "c_b_h"."user_id"               AS "c_b_h_user_id",
       "c_b_h"."instance"              AS "c_b_h_instance",
       "c_b_h"."user_type"             AS "c_b_h_user_type",
       "c_b_h"."level"                 AS "c_b_h_level",
       "c_b_h"."status"                AS "c_b_h_status",
       "c_b_h"."note"                  AS "c_b_h_note",
       "c_b_h"."contact_id"            AS "c_b_h_contact_id",
       "c_b_h"."cached_name"           AS "c_b_h_cached_name",
       "c_b_h"."cached_update"         AS "c_b_h_cached_update",
       "c_b_h"."contact_meta"          AS "c_b_h_contact_meta",
       "c_b_h"."joined"                AS "c_b_h_joined",
       "c_b_h_n"."circle_id"           AS "c_b_h_n_circle_id",
       "c_b_h_n"."member_id"           AS "c_b_h_n_member_id",
       "c_b_h_n"."single_id"           AS "c_b_h_n_single_id",
       "c_b_h_n"."user_id"             AS "c_b_h_n_user_id",
       "c_b_h_n"."instance"            AS "c_b_h_n_instance",
       "c_b_h_n"."user_type"           AS "c_b_h_n_user_type",
       "c_b_h_n"."level"               AS "c_b_h_n_level",
       "c_b_h_n"."status"              AS "c_b_h_n_status",
       "c_b_h_n"."note"                AS "c_b_h_n_note",
       "c_b_h_n"."contact_id"          AS "c_b_h_n_contact_id",
       "c_b_h_n"."cached_name"         AS "c_b_h_n_cached_name",
       "c_b_h_n"."cached_update"       AS "c_b_h_n_cached_update",
       "c_b_h_n"."contact_meta"        AS "c_b_h_n_contact_meta",
       "c_b_h_n"."joined"              AS "c_b_h_n_joined",
       "c_b_j"."single_id"             AS "c_b_h_n_j_single_id",
       "c_b_j"."circle_id"             AS "c_b_h_n_j_circle_id",
       "c_b_j"."level"                 AS "c_b_h_n_j_level",
       "c_b_j"."inheritance_first"     AS "c_b_h_n_j_inheritance_first",
       "c_b_j"."inheritance_last"      AS "c_b_h_n_j_inheritance_last",
       "c_b_j"."inheritance_path"      AS "c_b_h_n_j_inheritance_path",
       "c_b_j"."inheritance_depth"     AS "c_b_h_n_j_inheritance_depth",
       "c_b_h_g"."unique_id"           AS "c_b_h_g_unique_id",
       "c_b_h_g"."name"                AS "c_b_h_g_name",
       "c_b_h_g"."display_name"        AS "c_b_h_g_display_name",
       "c_b_h_g"."sanitized_name"      AS "c_b_h_g_sanitized_name",
       "c_b_h_g"."source"              AS "c_b_h_g_source",
       "c_b_h_g"."description"         AS "c_b_h_g_description",
       "c_b_h_g"."settings"            AS "c_b_h_g_settings",
       "c_b_h_g"."config"              AS "c_b_h_g_config",
       "c_b_h_g"."contact_addressbook" AS "c_b_h_g_contact_addressbook",
       "c_b_h_g"."contact_groupname"   AS "c_b_h_g_contact_groupname",
       "c_b_h_g"."creation"            AS "c_b_h_g_creation",
       "c_b_d"."circle_id"             AS "c_b_d_circle_id",
       "c_b_d"."member_id"             AS "c_b_d_member_id",
       "c_b_d"."single_id"             AS "c_b_d_single_id",
       "c_b_d"."user_id"               AS "c_b_d_user_id",
       "c_b_d"."instance"              AS "c_b_d_instance",
       "c_b_d"."user_type"             AS "c_b_d_user_type",
       "c_b_d"."level"                 AS "c_b_d_level",
       "c_b_d"."status"                AS "c_b_d_status",
       "c_b_d"."note"                  AS "c_b_d_note",
       "c_b_d"."contact_id"            AS "c_b_d_contact_id",
       "c_b_d"."cached_name"           AS "c_b_d_cached_name",
       "c_b_d"."cached_update"         AS "c_b_d_cached_update",
       "c_b_d"."contact_meta"          AS "c_b_d_contact_meta",
       "c_b_d"."joined"                AS "c_b_d_joined",
       "c_o"."unique_id"               AS "c_o_unique_id",
       "c_o"."name"                    AS "c_o_name",
       "c_o"."display_name"            AS "c_o_display_name",
       "c_o"."sanitized_name"          AS "c_o_sanitized_name",
       "c_o"."source"                  AS "c_o_source",
       "c_o"."description"             AS "c_o_description",
       "c_o"."settings"                AS "c_o_settings",
       "c_o"."config"                  AS "c_o_config",
       "c_o"."contact_addressbook"     AS "c_o_contact_addressbook",
       "c_o"."contact_groupname"       AS "c_o_contact_groupname",
       "c_o"."creation"                AS "c_o_creation",
       "c_o_d"."circle_id"             AS "c_o_d_circle_id",
       "c_o_d"."member_id"             AS "c_o_d_member_id",
       "c_o_d"."single_id"             AS "c_o_d_single_id",
       "c_o_d"."user_id"               AS "c_o_d_user_id",
       "c_o_d"."instance"              AS "c_o_d_instance",
       "c_o_d"."user_type"             AS "c_o_d_user_type",
       "c_o_d"."level"                 AS "c_o_d_level",
       "c_o_d"."status"                AS "c_o_d_status",
       "c_o_d"."note"                  AS "c_o_d_note",
       "c_o_d"."contact_id"            AS "c_o_d_contact_id",
       "c_o_d"."cached_name"           AS "c_o_d_cached_name",
       "c_o_d"."cached_update"         AS "c_o_d_cached_update",
       "c_o_d"."contact_meta"          AS "c_o_d_contact_meta",
       "c_o_d"."joined"                AS "c_o_d_joined"
FROM "oc_circles_member" "c"
         LEFT JOIN "oc_circles_circle" "c_g" ON "c_g"."unique_id" = "c"."single_id"
         LEFT JOIN "oc_circles_circle" "c_b" ON "c_b"."unique_id" = "c"."circle_id"
         LEFT JOIN "oc_circles_circle" "c_o" ON "c"."invited_by" = "c_o"."unique_id"
         LEFT JOIN "oc_circles_membership" "c_g_j"
                   ON ("c_g_j"."single_id" = $1) AND ("c_g_j"."circle_id" = "c_g"."unique_id")
         LEFT JOIN "oc_circles_member" "c_g_d" ON ("c_g_d"."circle_id" = "c_g"."unique_id") AND ("c_g_d"."level" = $2)
         LEFT JOIN "oc_circles_membership" "c_b_j"
                   ON ("c_b_j"."single_id" = $3) AND ("c_b_j"."circle_id" = "c_b"."unique_id")
         LEFT JOIN "oc_circles_member" "c_b_i"
                   ON ("c_b_i"."single_id" = $4) AND ("c_b_i"."circle_id" = "c_b"."unique_id")
         LEFT JOIN "oc_circles_member" "c_b_d" ON ("c_b_d"."circle_id" = "c_b"."unique_id") AND ("c_b_d"."level" = $5)
         LEFT JOIN "oc_circles_circle" "c_b_j_k"
                   ON ("c_b_j"."circle_id" = "c_b_j_k"."unique_id") OR ("c_b_i"."circle_id" = "c_b_j_k"."unique_id")
         LEFT JOIN "oc_circles_member" "c_b_h" ON ("c_b_j"."inheritance_first" = "c_b_h"."single_id") AND
                                                  ("c_b_j"."circle_id" = "c_b_h"."circle_id")
         LEFT JOIN "oc_circles_member" "c_b_h_n" ON ("c_b_j"."single_id" = "c_b_h_n"."single_id") AND
                                                    ("c_b_j"."inheritance_last" = "c_b_h_n"."circle_id")
         LEFT JOIN "oc_circles_circle" "c_b_h_g" ON "c_b_h_g"."unique_id" = "c_b_h"."single_id"
         LEFT JOIN "oc_circles_member" "c_o_d" ON ("c_o_d"."circle_id" = "c_o"."unique_id") AND ("c_o_d"."level" = $6)
WHERE ("c"."circle_id" = $7)
  AND (((("c_b_j_k"."config" & 2) > $8) AND ("c_b_j"."level" = $9)) OR
       ((("c_b_j"."level" >= $10) OR ("c_b_i"."level" >= $11)) AND (("c_b_j_k"."config" & 2) = $12)) OR
       ((("c_b"."config" & 16) > $13) AND (("c_b"."config" & 8) > $14) AND (("c_b"."config" & 64) = $15)))
ORDER BY "c"."level" desc, "c"."cached_name" asc

After:

SELECT "c"."circle_id",
       "c"."member_id",
       "c"."single_id",
       "c"."user_id",
       "c"."instance",
       "c"."user_type",
       "c"."level",
       "c"."status",
       "c"."note",
       "c"."contact_id",
       "c"."cached_name",
       "c"."cached_update",
       "c"."contact_meta",
       "c"."joined",
       "c_g"."unique_id"           AS "c_g_unique_id",
       "c_g"."name"                AS "c_g_name",
       "c_g"."display_name"        AS "c_g_display_name",
       "c_g"."sanitized_name"      AS "c_g_sanitized_name",
       "c_g"."source"              AS "c_g_source",
       "c_g"."description"         AS "c_g_description",
       "c_g"."settings"            AS "c_g_settings",
       "c_g"."config"              AS "c_g_config",
       "c_g"."contact_addressbook" AS "c_g_contact_addressbook",
       "c_g"."contact_groupname"   AS "c_g_contact_groupname",
       "c_g"."creation"            AS "c_g_creation",
       "c_g_d"."circle_id"         AS "c_g_d_circle_id",
       "c_g_d"."member_id"         AS "c_g_d_member_id",
       "c_g_d"."single_id"         AS "c_g_d_single_id",
       "c_g_d"."user_id"           AS "c_g_d_user_id",
       "c_g_d"."instance"          AS "c_g_d_instance",
       "c_g_d"."user_type"         AS "c_g_d_user_type",
       "c_g_d"."level"             AS "c_g_d_level",
       "c_g_d"."status"            AS "c_g_d_status",
       "c_g_d"."note"              AS "c_g_d_note",
       "c_g_d"."contact_id"        AS "c_g_d_contact_id",
       "c_g_d"."cached_name"       AS "c_g_d_cached_name",
       "c_g_d"."cached_update"     AS "c_g_d_cached_update",
       "c_g_d"."contact_meta"      AS "c_g_d_contact_meta",
       "c_g_d"."joined"            AS "c_g_d_joined"
FROM "oc_circles_member" "c"
         LEFT JOIN "oc_circles_circle" "c_g" ON "c_g"."unique_id" = "c"."single_id"
         LEFT JOIN "oc_circles_membership" "c_g_j"
                   ON ("c_g_j"."single_id" = $1) AND ("c_g_j"."circle_id" = "c_g"."unique_id")
         LEFT JOIN "oc_circles_member" "c_g_d" ON ("c_g_d"."circle_id" = "c_g"."unique_id") AND ("c_g_d"."level" = $2)
WHERE "c"."circle_id" = $3
ORDER BY "c"."level" desc, "c"."cached_name" asc

@provokateurin provokateurin added this to the Nextcloud 32 milestone Apr 14, 2025
@provokateurin provokateurin force-pushed the perf/memberrequest/remove-unused-left-joins branch from f081ecb to b754c91 Compare April 14, 2025 08:08
@provokateurin provokateurin force-pushed the perf/memberrequest/remove-unused-left-joins branch from 1d8c2ef to f63b1fd Compare June 2, 2025 11:10
@provokateurin provokateurin enabled auto-merge June 2, 2025 11:10
@provokateurin provokateurin merged commit 312fb93 into master Jun 2, 2025
31 checks passed
@provokateurin provokateurin deleted the perf/memberrequest/remove-unused-left-joins branch June 2, 2025 11:22
@provokateurin
Copy link
Member Author

/backport to stable31

@provokateurin
Copy link
Member Author

/backport to stable30

@provokateurin
Copy link
Member Author

/backport to stable29

mejo- added a commit that referenced this pull request Jun 4, 2025
PR #1969 broke members management in Collectives.

Collectives needs the initiator of a request to check if the current
user is an (inherited) member of non-user members (like circles and
groups).

Signed-off-by: Jonas <[email protected]>
backportbot bot pushed a commit that referenced this pull request Jun 4, 2025
PR #1969 broke members management in Collectives.

Collectives needs the initiator of a request to check if the current
user is an (inherited) member of non-user members (like circles and
groups).

Signed-off-by: Jonas <[email protected]>
backportbot bot pushed a commit that referenced this pull request Jun 4, 2025
PR #1969 broke members management in Collectives.

Collectives needs the initiator of a request to check if the current
user is an (inherited) member of non-user members (like circles and
groups).

Signed-off-by: Jonas <[email protected]>
backportbot bot pushed a commit that referenced this pull request Jun 4, 2025
PR #1969 broke members management in Collectives.

Collectives needs the initiator of a request to check if the current
user is an (inherited) member of non-user members (like circles and
groups).

Signed-off-by: Jonas <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants