From 88e70bff4d7aac9d529df1f078d4f6b6ede638ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?JP=20Cuevas=20Lav=C3=ADn?= Date: Fri, 7 Aug 2020 16:03:51 -0400 Subject: [PATCH] psql :optimized_sql strategy now updates a single row The planner may choose to generate a plan that executes a nested loop over the LIMITing subquery, causing more UPDATEs than LIMIT --- lib/delayed/backend/active_record.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/delayed/backend/active_record.rb b/lib/delayed/backend/active_record.rb index 62b186a1..799649f7 100644 --- a/lib/delayed/backend/active_record.rb +++ b/lib/delayed/backend/active_record.rb @@ -131,7 +131,7 @@ def self.reserve_with_scope_using_optimized_postgres(ready_scope, worker, now) # use 'FOR UPDATE' and we would have many locking conflicts quoted_name = connection.quote_table_name(table_name) subquery = ready_scope.limit(1).lock(true).select("id").to_sql - sql = "UPDATE #{quoted_name} SET locked_at = ?, locked_by = ? WHERE id IN (#{subquery}) RETURNING *" + sql = "WITH pending AS (#{subquery}) UPDATE #{quoted_name} SET locked_at = ?, locked_by = ? FROM pending WHERE #{quoted_name}.id = pending.id RETURNING *" reserved = find_by_sql([sql, now, worker.name]) reserved[0] end