Оптимизация запросов в 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?

Спасибо за прочтение!