Оптимизация запросов в MVC Framework
MVC — Model View Controller, один из самых популярных фреймворков, используемых в разработке программного обеспечения. Есть куча ошибок, которые я сделал, и я видел, как другие делают эти ошибки.
Я использую MVC в течение многих лет и использовал его на разных языках. Несколько популярных MVC-фреймворков, с которыми я работал, — это Ruby On Rails, Django, Revel и т. д.
Есть много причин, по которым разработчики допускают эти ошибки. Вот несколько распространенных причин, которые я заметил:
- Новички допускают ошибки из-за неопытности.
- Эксперты привыкают к структуре и ошибкам.
- Быстрое изменение, на самом деле не продуманное изменение.
Одной из самых распространенных ошибок, влияющих на производительность приложения, является — запрос базы данных в коде представления.
Я буду использовать Ruby On Rails и ERB, чтобы продемонстрировать проблемы, которые запросы могут вызывать в представлениях.
В этой статье я продемонстрирую использование Ruby On Rails и ERB. Это может быть применено к любой структуре MVC.
n + 1 запрос
Допустим, у нас есть следующие две модели:
Давайте рассмотрим приложение для ведения блога, которое имеет следующие две модели: Блог и Комментарий:
И давайте предположим, что есть маршрут GET /blogs, который отображает все блоги с одним комментарием в каждом блоге.
Вот контроллер для получения всех блогов:
Представление «app/views/blogs/index.html.erb» вызывается контроллером для отображения страницы со всеми блогами. А «app/views/blogs/_blog.html.erb» — это частичный блог для отображения блога.
В этом случае, если в таблице blogs 100 блогов, будет выполнено 1 + 100 запросов для отображения страницы index.html:
- 1 запрос, чтобы получить все блоги из таблицы блогов.
- В частичном представлении при вызове blog.comments выполняется запрос к таблице комментариев, чтобы получить комментарии для каждого блога. Это считается до 100.
Решение
Та же работа может быть выполнена с 1 или максимум 2 запросами. В Rails это называется нетерпеливой загрузкой. Вместо выполнения запросов в представлении комментарии загружаются в сам контроллер при запросе блогов.
Это делает два запроса:
Первый запрос — получение всех блогов, а второй — получение всех комментариев для всех идентификаторов блогов из результата первого запроса.
Это уменьшает количество запросов до 2. То же самое можно сделать с помощью JOIN.
Рассеянный код
Написание запросов в представлениях может сделать ваш код плохим и трудным для понимания. Новому разработчику может быть слишком сложно понять, если он посмотрит на контроллер и вывод.
Решение
Написание запросов к БД в моделях и вызов их в контроллерах — суть фреймворка MVC. Такого правила нет, но следование соглашениям MVC сделает ваш код легким для понимания и изменения.
Производительность БД
Больше запросов означает большую нагрузку на БД. Когда запросы происходят из представления, и это один из часто вызываемых API, это создает ненужную нагрузку на БД.
Когда запросы выполняются из представлений, как показано в примере, БД вызывается при каждом частичном рендеринге представления.
Решение
Оптимизация запросов к БД путем тщательного проектирования моделей и контроллеров может снизить нагрузку на серверы БД.
Заключение
Хотя я привел пример Ruby on Rails, эта концепция может относиться к любой среде MVC.
Я видел, как разработчики довольно часто допускают такие ошибки, иногда неосознанно, а в основном осознанно. Я ловил это в обзорах, делал такие ошибки и сам много раз подчищал такой код.
Приведенные выше примеры следует рассматривать с точки зрения понимания концепции. Код не оптимизирован.
Сталкивались ли вы с такими проблемами с инфраструктурой MVC?
Спасибо за прочтение!