User#authorized_projects is slow
This method is called in a whole lot of places while generally performing not too good (see http://performance.gitlab.net/dashboard/db/method-call-timings?var-process_type=rails&var-method=User%23authorized_projects). This is most likely due to two reasons:
- The list of authorized projects includes all public and internal projects, this list is rather large
- The query uses a UNION to merge the above projects together with the projects a user has explicit access to, producing a rather large result set
For the UNION part we could use an OR
but this is tricky since Rails 4 doesn't let you easily generate OR
statements. More info on this can be found in https://gitlab.com/gitlab-org/gitlab-ce/issues/14257.
Thinking of it perhaps we can change the logic. Whenever we check if a user has access to a project the logic basically comes down to:
if user.authorized_projects.include?(some_project)
...
end
For code such as this we don't actually need all the public/internal projects, instead we could do something like:
if user.authorized_projects.include?(some_project) || some_project.public? || some_project.internal?
...
end
This removes the need for ever having to query a full list of all public/internal projects. This in turn also removes the need for generating OR statements. However, depending on how we use the code this may not be possible.