ilyaplot
@ilyaplot
PHP программист

Почему Yii2 генерирует дополнительные запросы?

Пытаюсь избежать дополительного запроса, возникающего при выборке из двух таблиц.
Имеется модель 1
class Melody extends ActiveRecord
{

    public static function tableName()
    {
        return 'cms.melody';
    }

    public function getArtist()
    {
        return $this->hasOne(Artist::className(), ['artist_id' => 'artist_id']);
    }
    //....
}


Модель2
class Artist extends ActiveRecord
{
    public static function tableName()
    {
        return 'cms.artist';
    }
    //.....
}


Делаю выборку:
songs = Melody::find()
                ->alias('m')
                ->select([
                    'melody_id' => 'm.melody_id',
                    '"cms"."artist".*'
                ])
                ->joinWith('artist')
                ->all();


Получаю 2 запроса

1:
SELECT "m"."melody_id" AS "melody_id", "cms"."artist".* 
       FROM "cms"."melody" "m" inner join "cms"."artist" ON "m"."artist_id" = "cms"."artist"."artist_id"


2:
SELECT * FROM "cms"."artist" WHERE "artist_id" IN (1200, 2, 500, 4142, 364, 434, 1918, 1906, 13290, 9119, 1916, 5073, 72, 8351, 1316, 1694, 9926, 1822, 1894, 2040, 1074, 872, 8475, 10221, 10215, 552, 17792, 2000, 2080, 180, 1806, 1306, 6281, 16371, 1858, 8596, 892, 1534, 11766, 14104, 13172, 4917, 11058, 7040, 5789, 5400, 2108, 4864, 312, 276, 5918, 17497, 3903, 182, 564, 1670, 6602, 5074, 6922, 9613, 13430, 6773, 6232, 2036, 7014, 4289, 6529, 858, 1488, 1498, 4439, 17814, 82, 13250, 84, 1448, 164, 15551, 18288, 2102, 2100, 1444, 7509, 4947, 9018, 4338, 6691, 13438, 1418, 146, 814, 8715, 5349, 2182, 2044, 12109, 5913, 812, 1736, 98, 1018, 14500, 11312, 5055, 5058, 216, 102, 15808, 5061, 648)


Не могу понять, как избежать второго запроса и возможно ли это вообще? Не очень хочется чистый sql использовать из-за использования возможностей AR
  • Вопрос задан
  • 587 просмотров
Решения вопроса 1
VGrabko
@VGrabko
Golang, Php, Js
Потому что вы абстрагированы от управления запросами.
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
Попробуйте вместо joinWith() использовать leftJoin(Artist::className(), '`cms`.`id` = `m`.`artist_id')
Ответ написан
@Sergi0Limit
public function getArtist()
    {
        return $this->hasOne(Artist::className(), ['artist_id' => 'artist_id']);
    }

уберите и должно пропасть.
Но чем вам мешает второй запрос? Yii вам выбрал всех артистов относящихся к запросу за два запроса вместо N запросов

А еще у вас должны были быть запросы получения информации о таблицах, они вам не мешают?)
Хотите контролировать запросы - не используйте AR ни в каком виде. Только нативные запросы php, только хардкор!)
Ответ написан
@matios
Technical Team Lead
Читайте внимательно документацию

Если по-русски, то теперь релейшены работают не так, как в Yii1. Сейчас вместо одного запроса с кучей JOIN'ов выполняются несколько запросов использую IN (...). Не раз уже об этом говорилось. По ссылке все написано
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы