mirror of
https://github.com/discourse/discourse.git
synced 2025-03-09 14:34:35 +00:00
PERF: Use native postgres upsert for ApplicationRequest (#20706)
Using `create_or_find_by!`, followed by `update_all!` requires two or three queries (two when the row doesn't already exist, three when it does). Instead, we can use postgres's native `INSERT ... ON CONFLICT ... DO UPDATE SET` feature to do the logic in a single atomic call.
This commit is contained in:
parent
6b5743ba3c
commit
303f97ce89
@ -32,20 +32,14 @@ class ApplicationRequest < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.write_cache!(req_type, count, date)
|
def self.write_cache!(req_type, count, date)
|
||||||
id = req_id(date, req_type)
|
|
||||||
where(id: id).update_all(["count = count + ?", count])
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.req_id(date, req_type, retries = 0)
|
|
||||||
req_type_id = req_types[req_type]
|
req_type_id = req_types[req_type]
|
||||||
|
|
||||||
create_or_find_by!(date: date, req_type: req_type_id).id
|
DB.exec(<<~SQL, date: date, req_type_id: req_type_id, count: count)
|
||||||
rescue StandardError # primary key violation
|
INSERT INTO application_requests (date, req_type, count)
|
||||||
if retries == 0
|
VALUES (:date, :req_type_id, :count)
|
||||||
req_id(date, req_type, 1)
|
ON CONFLICT (date, req_type)
|
||||||
else
|
DO UPDATE SET count = application_requests.count + excluded.count
|
||||||
raise
|
SQL
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.stats
|
def self.stats
|
||||||
|
Loading…
x
Reference in New Issue
Block a user