From 1f636c445bcbc66b1765bcc3966887adcb14bdbf Mon Sep 17 00:00:00 2001 From: Guo Xiang Tan Date: Thu, 6 Sep 2018 14:29:45 +0800 Subject: [PATCH] PERF: Add fast path to find uploads before resorting to `LIKE` query. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For a normal upload url Before ``` Warming up -------------------------------------- 264.000 i/100ms Calculating ------------------------------------- 2.754k (± 8.4%) i/s - 13.728k in 5.022066s ``` After ``` Warming up -------------------------------------- 341.000 i/100ms Calculating ------------------------------------- 3.435k (±11.6%) i/s - 17.050k in 5.045676s ``` --- app/models/upload.rb | 12 ++++++------ spec/models/upload_spec.rb | 5 +++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/models/upload.rb b/app/models/upload.rb index 4ab07e4ce1b..f035751098f 100644 --- a/app/models/upload.rb +++ b/app/models/upload.rb @@ -175,12 +175,12 @@ class Upload < ActiveRecord::Base end return if uri&.path.blank? - - path = uri.path[/(\/original\/\dX\/[\/\.\w]+)/, 1] - - return if path.blank? - - Upload.find_by("url LIKE ?", "%#{path}") + data = uri.path.match(/(\/original\/\dX\/[\/\.\w]+\/([a-zA-Z0-9]+)[\.\w]+)/) + return if data.blank? + sha1 = data[2] + upload = nil + upload = Upload.find_by(sha1: sha1) if sha1 + upload || Upload.find_by("url LIKE ?", "%#{data[1]}") end def self.migrate_to_new_scheme(limit = nil) diff --git a/spec/models/upload_spec.rb b/spec/models/upload_spec.rb index a52af4a0bd5..b19bcd3d3e3 100644 --- a/spec/models/upload_spec.rb +++ b/spec/models/upload_spec.rb @@ -74,8 +74,9 @@ describe Upload do end context ".get_from_url" do - let(:url) { "/uploads/default/original/3X/1/0/10f73034616a796dfd70177dc54b6def44c4ba6f.png" } - let(:upload) { Fabricate(:upload, url: url) } + let(:sha1) { "10f73034616a796dfd70177dc54b6def44c4ba6f" } + let(:url) { "/uploads/default/original/3X/1/0/#{sha1}.png" } + let(:upload) { Fabricate(:upload, url: url, sha1: sha1) } it "works when the file has been uploaded" do expect(Upload.get_from_url(upload.url)).to eq(upload)