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

Remove joins to space and org tables for permissions #2533

Conversation

andy-paine
Copy link
Contributor

@andy-paine andy-paine commented Oct 7, 2021

A short explanation of the proposed change

Don't join to space/org tables just to filter permissions by guid when we could use id instead

An explanation of the use cases your change solves

Unfiltered (i.e. no space_guids or org_guids query params) will have 2 less joins in this (fairly large) statement to do so queries should be simpler and just faster.

Info

There were 2 joins performed to the space and org tables just so that
the permissions check could filter by readable space guids and readable
org guids. As we fetch the entire space/org object in the permissions
check, it is simple to just grab the IDs instead. As the tables
reference the space_id and organization_id, we can avoid joining to
space and org and just do a WHERE IN check on those columns instead. For
filtering, the API still accepts GUIDs so the joins are still performed
there.

Links to any other associated PRs

Similar theme to #2528 in terms of speeding up this endpoint

  • I have reviewed the contributing guide

  • I have viewed, signed, and submitted the Contributor License Agreement

  • I have made this pull request to the main branch

  • I have run all the unit tests using bundle exec rake

  • I have run CF Acceptance Tests

@philippthun philippthun force-pushed the reduce-service-plan-joins-further branch from 4e3e7bc to a068b49 Compare October 11, 2021 11:42
There were 2 joins performed to the space and org tables just so that
the permissions check could filter by readable space guids and readable
org guids. As we fetch the entire space/org object in the permissions
check, it is simple to just grab the IDs instead. As the tables
reference the space_id and organization_id, we can avoid joining to
space and org and just do a WHERE IN check on those columns instead. For
filtering, the API still accepts GUIDs so the joins are still performed
there.

Co-authored-by: Philipp Thun <[email protected]>
@philippthun philippthun force-pushed the reduce-service-plan-joins-further branch from a068b49 to 4cb16d8 Compare October 11, 2021 12:19
- Check if the list of given roles contains a space/org role and omit
  the corresponding subquery if not.
- Combine the subqueries in a "SELECT x WHERE y OR z" query that can
  deal with y or z being 'nil'.
- Also reduce queries and selected data in has_any_roles?; dataset.any?
  retrieves all data from the database, whereas dataset.empty? issues a
  "SELECT 1 AS one"
@philippthun philippthun mentioned this pull request Oct 11, 2021
5 tasks
@andy-paine andy-paine marked this pull request as ready for review October 11, 2021 13:34
@JenGoldstrich
Copy link
Contributor

@MerricdeLauney and I deployed this to a bosh lite, and ran some basic tests to make sure role membership behaved as expected.

This seems good to us but we wanted to ask @monamohebbi if she had any input here as she has recently refactored this code.

@MerricdeLauney MerricdeLauney merged commit 1951ac1 into cloudfoundry:main Nov 2, 2021
philippthun added a commit to sap-contributions/cloud_controller_ng that referenced this pull request Jul 11, 2022
There are already several PRs (see below [1]) that change dataset.any?
to !dataset.empty? or otherwise mention the difference between these two
statements. Whereas the first one fetches all data from the database to
then check if the resulting array contains at least one element, the
second statement does a 'select 1 as one from table limit 1' query that
has a far better performance.

Fortunately there is a Sequel extension (see [2]) that 'fixes' this
misleading behavior; so instead of searching for more places where we
could change the implementation, using dataset.any? should now be
equivalent to !dataset.empty? and everyone can choose freely which one
to use.

[1]
cloudfoundry#2117
cloudfoundry#2533
cloudfoundry#2803
cloudfoundry#2855

[2] https://sequel.jeremyevans.net/rdoc-plugins/files/lib/sequel/extensions/any_not_empty_rb.html
will-gant pushed a commit to sap-contributions/cloud_controller_ng that referenced this pull request Dec 16, 2022
There are already several PRs (see below [1]) that change dataset.any?
to !dataset.empty? or otherwise mention the difference between these two
statements. Whereas the first one fetches all data from the database to
then check if the resulting array contains at least one element, the
second statement does a 'select 1 as one from table limit 1' query that
has a far better performance.

Fortunately there is a Sequel extension (see [2]) that 'fixes' this
misleading behavior; so instead of searching for more places where we
could change the implementation, using dataset.any? should now be
equivalent to !dataset.empty? and everyone can choose freely which one
to use.

[1]
cloudfoundry#2117
cloudfoundry#2533
cloudfoundry#2803
cloudfoundry#2855

[2] https://sequel.jeremyevans.net/rdoc-plugins/files/lib/sequel/extensions/any_not_empty_rb.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants