Использование представлений MySQL в приложении Ruby on Rails для повышения производительности - PullRequest
10 голосов
/ 10 февраля 2009

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

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

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

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

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

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 ...

Ответы [ 4 ]

5 голосов
/ 16 февраля 2009

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

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

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

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

1 голос
/ 10 февраля 2009

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

1 голос
/ 10 февраля 2009

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...