От автора: приветствую вас, друзья. Итак, мы продолжаем цикл статей, посвященных знакомству с фреймворком Yii2. Данная статья, как и две предыдущих, будет посвящена работе с компонентом Yii2 модели. При изучении этого понятия сложно обойти такую тему, как жадная загрузка. Из статьи вы узнаете, что означает жадная загрузка данных и для чего она нужна.
Итак, напомню, в предыдущей статье мы с вами говорили о связях моделей. Благодаря связям, мы можем достаточно удобно и просто использовать связи один-к-одному и прочие для связывания таблиц и получения связанных данных. Например, как мы это и реализовали в предыдущей статье, связав модели категорий и постов. Благодаря этой связи, мы смогли получить объекты категорий, к которым относятся выбранные посты. Очень удобно.
Однако, в этом удобстве может скрываться один подводный камень. Давайте заглянем в Yii Debugger — инструмент, который расположен в правом нижнем углу страницы.
Заглянем во вкладку DB и обнаружим там 10 (в моем случае) выполненных SQL запросов.
А ведь у нас всего-то несколько тестовых записей в БД. А представьте, если записей на страницу будет несколько десятков? Обратите внимание на запросы, которые выполняет фреймворк. Мы видим там однотипные запросы получения категории по ее id. И таких запросов будет столько, сколько выводится постов. Почему так происходит?
А происходит так из-за так называемой ленивой загрузки данных (отложенная загрузка). Именно она и использовалась при обращении к виртуальному свойству, доступному нам после реализации связи моделей. Использовать ленивую загрузку очень удобно поскольку она работает только тогда, когда она нам нужна и мы вызываем ее. В этом легко убедиться, если мы сейчас уберем обращение к виртуальному свойству из представления, вот эту вот строку:
1 |
<p>Категория: <?= $post->category->name ?></p> |
После этого у нас останется всего 3 запроса к БД.
Но как быть, если связи моделей все же нужны? В данном случае вместо отложенной загрузки нам нужно просто обратиться к другому варианту загрузки связанных данных в Yii2 — жадная загрузка. Этот вариант выбирает данные всегда, вне зависимости от того, нужны ли они нам. В этом одно из его отличий от отложенной загрузки.
Для того, чтобы использовать жадную загрузку данных, нам достаточно добавить метод with(), указав в качестве параметра наименование связи (геттер связи в модели).
1 |
$posts = Post::find()->with('category')->all(); |
Все, больше ничего менять не нужно. Обращение к свойству, которое при жадной загрузке перестает быть виртуальным (помним, что жадная загрузка всегда загружает связанные данные, в отличие от ленивой, где данные загружаются только при обращении к ним), так вот, обращение к свойству в коде представления остается неизменным, давайте его вернем в код:
1 |
<p>Категория: <?= $post->category->name ?></p> |
Теперь проверим запросы к БД. Вместо запросов вида SELECT * FROM category WHERE id = … для каждого поста, мы увидим один запрос вида SELECT * FROM category WHERE id
IN (…). Этим запросом жадно выбираются все категории для получаемых на страницу постов.
Резюмируя, можно отметить, что в зависимости от ситуации вы можете использовать либо отложенную, либо жадную загрузку данных. Не забывайте об этом и используйте инструмент Yii Debugger для отслеживания производительности вашего приложения, чтобы не столкнуться с ситуацией, когда будут отрабатываться десятки запросов вместо одного.
На этом мы завершим текущую статью. Больше о фреймворке вы можете узнать из наших бесплатных или платных уроков. Также создание простейшего блога на Yii2 можно посмотреть в этом цикле уроков.