summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorick Peterse <yorickpeterse@gmail.com>2015-10-29 17:51:49 +0100
committerYorick Peterse <yorickpeterse@gmail.com>2015-10-30 12:00:58 +0100
commita9df714764d6138bf162acd82b780ca82a21864b (patch)
tree5b04d07bc66a3139e6fca1bd6bd5d977ccc78634
parentbba46623c20de52942c85eb2aba3649e3f4ba296 (diff)
downloadgitlab-ce-a9df714764d6138bf162acd82b780ca82a21864b.tar.gz
Use a subquery with IDs only for find_by_any_email
This further improves performance of User.find_by_any_email and is roughly twice as fast as the previous UNION setup. Thanks again to @dlemstra for suggesting this.
-rw-r--r--app/models/user.rb16
1 files changed, 7 insertions, 9 deletions
diff --git a/app/models/user.rb b/app/models/user.rb
index 66db70080b7..67fef1c1e6a 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -235,15 +235,13 @@ class User < ActiveRecord::Base
# Find a User by their primary email or any associated secondary email
def find_by_any_email(email)
- # Arel doesn't allow for chaining operations on union nodes, thus we have
- # to write this query by hand. See the following issue for more info:
- # https://github.com/rails/arel/issues/98.
- sql = '(SELECT * FROM users WHERE email = :email)
- UNION
- (SELECT users.*
- FROM emails
- INNER JOIN users ON users.id = emails.user_id
- WHERE emails.email = :email)
+ sql = 'SELECT *
+ FROM users
+ WHERE id IN (
+ SELECT id FROM users WHERE email = :email
+ UNION
+ SELECT emails.user_id FROM emails WHERE email = :email
+ )
LIMIT 1;'
User.find_by_sql([sql, { email: email }]).first