I need to add a counter cache to a database that has about 4 million rows. The normal way I would do this is in a migration like so:
class AddClicksCounterCacheToPosts < ActiveRecord::Migration
def change
add_column :posts, :clicks_count, :integer
Post.find_each { |post| Post.reset_counters(post.id, :clicks) }
end
end
However this is much too slow. I came across a way to do this in pure SQL but it looks like it was written for MySQL and I can't seem to get it to work for Postgres. Here's what I am trying:
class AddClicksCounterCacheToPosts < ActiveRecord::Migration
def change
add_column :posts, :clicks_count, :integer
execute <<-eos
update posts, (select
id as post_id, coalesce(count, 0) as count
from posts left join
(select post_id, count(id) as count from clicks group by post_id) as count_table
on
posts.id = count_table.post_id) as count_table
set
posts.clicks_count = count_table.count
where
posts.id = count_table.post_id
eos
end
end
And this is the error I get:
ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR: syntax error at or near ","
I'm pretty sure commas are allowed in postgres but to be honest I don't write too much raw postgres so I'm not sure.
Any idea how to convert this to Postgres?