Использование представлений MySQL в приложении Ruby on Rails для повышения производительности

У меня возникают проблемы с производительностью в проекте rails (работает на rails 2.0.5), например, на моих страницах администрирования пользователей.

моя модель пользователя имеет много отношений (детали, адреса, роли...), которые загружаются с активной загрузкой. Это создает действительно огромные SQL-запросы, в некоторых случаях для загрузки 30 пользователей требуется почти минута. С другой стороны, удаление активной загрузки создает сотни запросов, в конце концов у меня такая же проблема: загрузка страницы происходит медленно.

Я использовал для разработки на Java и Oracle, для таких больших запросов, которые я использовал для создания представлений, эти представления затем кэшировались для более быстрого рендеринга. Было очень скучно поддерживать, поскольку мне приходилось вручную обновлять поля базы данных в сценариях представлений и т.д.

НО у него действительно были фантастические выступления.... так что мне было интересно, если кто-нибудь когда-либо пытался реализовать что-то, чтобы воспользоваться преимуществами представлений Mysql в активной записи?

Я просто сделал некоторые базовые тесты, вот мой взгляд (всего несколько полей для примера, у меня есть стандартная таблица пользователей Restful Authentication и большая таблица "Детали" для личных данных):

CREATE VIEW users_vs AS SELECT
users.id              ,          
users.login           ,          
users.email           ,          
details.last_name           ,
details.first_name          ,
details.phone               ,
details.fax                 ,
FROM `users`   LEFT OUTER JOIN `details` ON details.user_id = users.id ;

Тогда модель:

class UsersV < ActiveRecord::Base
end

Пробовал несколько вещей в моей консоли:

u=UsersV.find(:first)  # ok !
u=UsersV.find_by_last_name('smith') #=> ok !
us=UsersV.find_all_by_last_name('smith') #=> ok too !

глядя на журнал, простые запросы обрабатываются так же, как и любые табличные запросы

Конечно, эти поддельные модели будут просто использоваться для чтения данных.

Мне интересно:

  • Если кто-то уже пробовал это?

  • если это хорошая идея?

  • если я должен искать что-то вроде memcached, а не...

Ответ 1

"Проблема" с представлениями (и в этом случае вам, вероятно, понадобится материализованное представление, предполагающее, что данные, на которых основан сложный запрос, не часто меняются) заключается в том, что вы нарушаете DRY'ness Rails, чтобы в некоторой степени (добавление модели UserV для представления, которое утверждают пуристы, является дублированием модели пользователя.)

Таким образом, идеальным решением было бы получить максимальную отдачу от СУБД для вашего сложного запроса. Memcached не сможет вам помочь, если оставшиеся незатребованные запросы все еще занимают много времени (вам все равно придется запускать их для заполнения memcached), или если вы не можете разместить немного времени (например, кэшированные результаты, t должны быть точными в реальном времени) и/или используемые таблицы часто изменяются.

  • В MySQL посмотрите, можете ли вы оптимизировать запрос дальше, чтобы вместо секунд потребовалось миллисекунды ( добавить соответствующие индексы, запустите ANALYZE и т.д.).
  • Если у вас есть возможность использовать/тестировать другую СУБД, такую ​​как Postgres, обязательно попробуйте. MySQL ужасно плох со сложными объединениями (InnoDB) по сравнению с другими экономичными механизмами, такими как Oracle и Postgres. Я переключился с MySQL на Postgres и сложные объединения, которые занимали бы 30s + в MySQL (со всеми показателями на месте), занимая миллисекунды на Postgres. Если вы играете с Postgres, используйте графический инструмент планирования PGAdminIII.

Ответ 2

Я регулярно использую представления таблиц в Rails, и я очень доволен этим. Rails рассматривают их как обычные таблицы, поскольку вы используете их только для чтения записей (что является моим обычным сценарием). Пока ваше представление состоит только из одной таблицы, вы также можете сделать с ней все другие вещи CRUD. Итак, мой ответ: просто сделайте это.

Ответ 3

http://github.com/aeden/rails_sql_views/tree/master

& uarr; Чтобы создать представление в процессе миграции. Я бы использовал их только в крайних случаях, поскольку они скрывают логику от вашего приложения, и это обычно не хорошо.

Если у вас есть много связанных данных, вы можете посмотреть на использование чего-то вроде DataMapper вместо ActiveRecord с Rails, поскольку оно поддерживает ленивые данные по мере необходимости.

Ответ 4

Убедитесь, что включено Query Query, которое кэширует результирующий набор. У меня было несколько ситуаций, когда многие запросы без подключений по сравнению с несколькими запросами с объединениями на самом деле быстрее, даже если вы делаете больше поездок на сервер.