Разрабатываю RESTful API на фреймворке Yii2. На данный момент делаю вторую версию API v2
. Задача следующая:
Сократить количество запросов к бд, при выборке.
Отправляется запрос на URL: api.com/v2/indicators&expand=tickers
.
В expand
я передаю связи, которые хочу вытянуть. Вообще в expand
можно предать до 20 связей. Данных в базе достаточно много, и поэтому Yii2
делает очень много запросов, для того чтобы получить все tickers
для indicators
.
Связь MANY_TO_MANY
.
Пример: В базе есть 300 индикаторов, у каждого индикатора есть много тикеров. Связь идет через junction table
, в модели Indicator
выглядит так:
public function getTickers(): ActiveQuery
{
return $this->hasMany(Ticker::class, ['id' => 'tickerId'])
->viaTable(RelationIndicatorTicker::tableName(), ['indicatorId' => 'id']);
}
Используется дефолтный ActiveController
и его дефолтный IndexAction
. Связи все тянет правильно, но делает примерно 300*20 = 6000 запросов, если у каждого индикатора будет по 20 тикеров(что так и есть).
Сейчас Yii2
в базу делает такие пустые запросы, которые исполняются по 6000 раз:
SELECT * FROM `ticker` WHERE 0=1
Вот скрин из NeorProfiler
Видно что у indicator
с id = 8
есть два тикера с id IN(40, 51)
. Т.е. все остальные запросы просто сплошной мусор. Как от этого можно избавиться? Есть ли какие-то варианты переопределить expand
?
Пробовал я еще переопределять дефолтный IndexAction
, и там переопределял prepareDataProvider
, писал свой метод для этого в котором получал:
$query = Indicator::find();
$expand = Yii::$app->getRequest->getQueryParam('expand');
$expand = explode(',', $expand);
foreach($expand as $relationName) {
// тут можно сделать проверку на реляцию, но сейчас не суть
$query = $query->joinWith($relationName);
}
Таким способом все работало и в базе не было "мусора", и вместо 6000 запросов было всего 3, разница очень большая. Есть ли какие-то другие, более "элегантные" способы решения данной проблемы?
<?php
return $this->hasMany(Ticker::class, ['id' => 'tickerId'])
->with('ticker') // по идее эта строчка должна помочь - это жадный запрос
->viaTable(RelationIndicatorTicker::tableName(), ['indicatorId' => 'id']);
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Доброго времени суток Подскажите пожалуйста как добавить image в Анонсы элемента? Я делаю так:
Всем приветДелаю небольшой проект на Ларавел, где нужно сгенерировать 4 случайные дни недели , включая сегодняшний