Жадная загрузка в Yii2, для тех кто хочет понять что это такое

в 13:14, , рубрики: sql, web, with, yii, yii2, yii2 framework, жадная загрузка, Разработка веб-сайтов

Пост рассказывает для чего необходимо использовать «жадную загрузку», вместо «ленивой загрузки», не претендует на идеал. И вряд ли заинтересует профессионалов, больше подходит для начинающих в изучении YII2.

Используем жадную загрузку в своем приложении. Допустим у нас имеется две таблицы с постами и категориями. У каждого поста возможна одна категория, у категорий 1 или более постов.

bd - mediarise.ru

Допустим мы скрудили модели, контроллеры, представления по этим таблицам. Заполним список постов. Обратите внимание, в колонке категорий отображаются сами названия категорий, а не id категорий.

bd - mediarise.ru

Отобразить название категорий можно в представлении: «views/post/index.php» изменив GridView таким образом:

<?php ...
use appmodelsCategory;
?>

 <?= GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => [
            ['class' => 'yiigridSerialColumn'],

            'id',
            [
                'attribute' => 'category_id',
                'filter' => Category::find()->select(['name', 'id'])->indexBy('id')->column(),
                'value' => 'category.name',
            ],
            'name',
            'content:ntext',

            ['class' => 'yiigridActionColumn'],
        ],
    ]); ?>

  //    'attribute' => 'category_id', к атрибуту category_id, добавляем значение 'value' => 'category.name', где name как раз после с названием категории
  //    'filter' => Category::find()->select(['name', 'id'])->indexBy('id')->column(), -- дает фильтрацию по название категорий
  //    'value' => 'category.name',

Вот как раз, здесь нам и пригодится «жадная загрузка». Дело в том, что если мы посмотрим sql — запросы нашего приложения.

bd - mediarise.ru

Мы увидим множество запросов из таблицы category, такого вида

SELECT * FROM `sb_category` WHERE `id`=x

Где x — id из постов — category_id. Если у нас будет выводится на странице 100, 500, 1000 постов, будет и столько же выборок в таблице post. В данном случае, если посмотреть по времени выполнения скрипта, запросы в БД выполняются быстро. Но если мы можем сэкономить ресурсы, почему бы этим не воспользоваться. Для этого создана «жадная загрузка». Жадная загрузка, это загрузка с избыточными данными, как бы с присоединенной таблицей.

В модели appmodelsPostSearc, в методе search, добавим жадную загрузку через метод with

    public function search($params)
    {
        $query = Post::find();
    public function search($params)
    {
        $query = Post::find()->with(['category']);

После этого смотрим на результат:

bd - mediarise.ru

Сейчас мы видим, вместо многочисленных запросов в БД, мы получаем всего 2. Выборку данных из таблиц psot и category.
Метод with собирает все поля category_id из таблицы post, и делает один запрос в БД, извлекая все категории по условию WHERE `id` IN (1, 2, 3, 4, 5). Т.е в where перечисляются все id, которые есть в первой выборке post

SELECT * FROM `sb_post` LIMIT 20

Для того что бы работала фильтрация, сортировка в GridView. Необходимо вместо with(), использовать joinWith().
joinWith() выполняет жадную загрузку и присоединяет дополнительную таблицу с помощью join и это дает нам возможность добавлять условия, сортировку.

Автор: MediaRise

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js