From 4175fe6987fb0ccd5be9f8b72c497d42f7a1cb5c Mon Sep 17 00:00:00 2001 From: Noah Botimer Date: Mon, 1 Jul 2024 13:11:27 -0400 Subject: [PATCH] Improve query performance by adjusting join conditions We originally attempted to map everything out with left joins and then apply the conditions that filter down to at most one matching row each (for direct user grants, institution memberships, network, or group memberships). It was conceptually correct, but the query optimizer did not apply the WHERE fully through memberships joins. This meant that, for institutions with many members, there was a cartesian product of grants to memberships to process. There are multiple approaches that solve this problem, including adjusting the associativity/grouping of the joins (so that the memberships inner join the users, thereby left joining at most one membership-user row). However, the flat construction of the ROM query code is attractive for its relative simplicity. By applying the literal username comparison at the institution and group memberships, we achieve the goal of left joining at most one membership. In production-scale measurements, this amounts to the same results being returned on the order of 2,000 times faster (e.g., 50ms vs 100s). --- lauth/app/repositories/grant_repo.rb | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/lauth/app/repositories/grant_repo.rb b/lauth/app/repositories/grant_repo.rb index da25931..a4703dd 100644 --- a/lauth/app/repositories/grant_repo.rb +++ b/lauth/app/repositories/grant_repo.rb @@ -46,10 +46,10 @@ def base_grants_for(username:, network:) .where(grants[:dlpsDeleted].is("f")) .left_join(users.name.dataset, userid: grants[:userid], dlpsDeleted: "f") .left_join(institutions.name.dataset, uniqueIdentifier: grants[:inst], dlpsDeleted: "f") - .left_join(institution_memberships.name.dataset, inst: :uniqueIdentifier, dlpsDeleted: "f") + .left_join(institution_memberships.name.dataset, inst: :uniqueIdentifier, userid: username, dlpsDeleted: "f") .left_join(Sequel.as(users.name.dataset, :inst_users), userid: :userid, dlpsDeleted: "f") .left_join(groups.name.dataset, uniqueIdentifier: grants[:user_grp], dlpsDeleted: "f") - .left_join(group_memberships.name.dataset, user_grp: :uniqueIdentifier, dlpsDeleted: "f") + .left_join(group_memberships.name.dataset, user_grp: :uniqueIdentifier, userid: username, dlpsDeleted: "f") .left_join(Sequel.as(users.name.dataset, :group_users), userid: :userid, dlpsDeleted: "f") .left_join(Sequel.as(network, :smallest), inst: institutions[:uniqueIdentifier]) .where( @@ -60,13 +60,11 @@ def base_grants_for(username:, network:) ), Sequel.&( Sequel.~(institutions[:uniqueIdentifier] => nil), - Sequel.~(Sequel[:inst_users][:userid] => nil), - {institution_memberships[:userid] => username} + Sequel.~(Sequel[:inst_users][:userid] => nil) ), Sequel.&( Sequel.~(groups[:uniqueIdentifier] => nil), - Sequel.~(Sequel[:group_users][:userid] => nil), - {group_memberships[:userid] => username} + Sequel.~(Sequel[:group_users][:userid] => nil) ), Sequel.&( Sequel.~(Sequel[:smallest][:inst] => nil),