Многие говорят что рельсы делают много запросов к базе данных, расчитывают на большую посещаемость, но наверное часто забывают что базу данных надо еще периодическиоптимизировать. Я предлагаю для этого сделать контролер доступный только для админа и создать екшин для оптимизации. Сначала получаем полный список таблиц в базе и по очереди оптимизируем их. Так как возможно одни из вас пользуются mysql а другие postgres, то этот код допойдет обоим.
def db_optimization
@tables = ActiveRecord::Base.connection.select_rows("show tables")
@tables = @tables - ["schema_info"]
@tables.flatten!
if params[:start]
@tables.each do |table|
case ActiveRecord::Base.establish_connection.config[:adapter]
when 'mysql'
ActiveRecord::Base.connection.execute("OPTIMIZE TABLE #{table} ")
when 'postgres'
ActiveRecord::Base.connection.execute("VACUUM #{table}; REINDEX table")
else
# ничего не делать
end
end
flash[:notice] = 'База ортимизирована.'
redirect_to :action => 'index'
end
end
OPTIMIZE TABLE works only for MyISAM, InnoDB, and ARCHIVE tables.
Но это еще не все на что стоит обратить внимание. Все знают что работа с базой происходит быстрее чем с файлами в системе, и вероятно все уже давно перевели хранение сессий в базу данных. В класах сессий не задумана очиста базы, по крайне мере я не нашел такого места и описания.
Исходя их практики за несколько месяце у нас на форуме таблица сессий выросла до 120 МБ. Думаю что поиск сесси каждый раз при просомтре страницы в таблице такого размера довольно емкое действие. По этому стоит удалять все сессии жизнь которых истекла. Проверяем это по полую upsated_at и удаляем все старые записи. Но при таком масовом удалении таблица не очищается пользостью так что приходиться ее оптимизивароть выше приведенным методом.
И так мой вариант решения добавить метод в appliucation.rb который будет дергаться по before_filter и при заходе админом мы будем удалять старые сесси.
application.rb
class ApplicationController < ActionController::Base
before_filter :clear_old_sessions
def clear_old_sessions
Sessions.destroy_all ["updated_at < ?", Time.now() - 14.days] if is_admin?
end