namespace :db do namespace :bloat do desc 'Поиск распухших таблиц' task :tables => :environment do redis = Redis::Namespace.new('db:bloat') connection = ActiveRecord::Base.connection connection.tables.each do |table_name| begin rows_counted = redis.hget('tables', table_name) unless rows_counted rows_counted = connection.select_value("select count(*) from #{table_name}") redis.hset('tables', table_name, rows_counted) end rows_counted = rows_counted.to_i next if rows_counted.zero? rows_estimated = connection. select_value("select reltuples::int4 from pg_class where oid = 'public.#{table_name}'::regclass"). to_i bloat = rows_estimated * 100 / rows_counted - 100 if bloat > 25 puts "#{table_name} > count: #{rows_counted}, estimate: #{rows_estimated}, bloat: #{bloat}" connection.execute "VACUUM ANALYZE #{table_name}" end rescue Exception => e puts e.message end end redis.expire('tables', 5.days) end desc 'Очистка кеша для распухших таблиц' task :clear_cache => :environment do Redis::Namespace.new('db:bloat').del('tables') end end end