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
  • Вопрос задан
  • 589 просмотров
Решения вопроса 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 (...). Не раз уже об этом говорилось. По ссылке все написано
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы