From 03417456f0b7db408bfefd28e5b9342889b7f711 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Wed, 7 Oct 2015 17:37:39 +0200 Subject: Revamp finding projects by namespaces By using a JOIN we can remove the need for using 2 separate queries to find a project by its namespace. Combined with an index (only needed for PostgreSQL) this reduces the query time from ~245 ms (~520 ms for the first call) down to roughly 10 ms (~15 ms for the first call). --- app/models/concerns/case_sensitivity.rb | 2 +- app/models/project.rb | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) (limited to 'app/models') diff --git a/app/models/concerns/case_sensitivity.rb b/app/models/concerns/case_sensitivity.rb index 49d350e092b..fe0cea8465f 100644 --- a/app/models/concerns/case_sensitivity.rb +++ b/app/models/concerns/case_sensitivity.rb @@ -6,7 +6,7 @@ module CaseSensitivity # Queries the given columns regardless of the casing used. # # Unlike other ActiveRecord methods this method only operates on a Hash. - def case_insensitive_where(params) + def iwhere(params) criteria = self cast_lower = Gitlab::Database.postgresql? diff --git a/app/models/project.rb b/app/models/project.rb index bb47b9abb03..f75082a35d0 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -40,6 +40,7 @@ class Project < ActiveRecord::Base include Referable include Sortable include AfterCommitQueue + include CaseSensitivity extend Gitlab::ConfigHelper extend Enumerize @@ -235,13 +236,18 @@ class Project < ActiveRecord::Base end def find_with_namespace(id) - return nil unless id.include?('/') - - id = id.split('/') - namespace = Namespace.by_path(id.first) - return nil unless namespace - - where(namespace_id: namespace.id).where("LOWER(projects.path) = :path", path: id.second.downcase).first + namespace_path, project_path = id.split('/') + + return nil if !namespace_path || !project_path + + # Use of unscoped ensures we're not secretly adding any ORDER BYs, which + # have a negative impact on performance (and aren't needed for this + # query). + unscoped. + joins(:namespace). + iwhere('namespaces.path' => namespace_path). + iwhere('projects.path' => project_path). + take end def visibility_levels -- cgit v1.2.3