Составление запроса

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Составление запроса

Сообщение unknownby »

В базе есть две таблицы, например, таблица заказов и договоров.
В заказах 40к записей и в договорах такое же количество.
Первая таблица связана со второй один ко многим.
Нужно составить запрос так, чтобы при получении хотя бы одного значения по связи прекращалась выборка и переходило к следующей записи.
Например, берем первую запись и у неё связь нашлась через 10 записей во второй таблице (хотя есть связь на 2000 строке и на 35000), нужно прекратить поиск и чтобы дальше взялась вторая запись и пошел поиск по второй таблице.
Было бы отлично, если реализация через joinWith и прописью какого-то значения в select().

Если говорить простыми словами, то нужно найти есть ли хоть один договор в заказах.
Суть в том, чтоб запрос работал быстро, т.к. в самом запросе ещё много различных связей с другими таблицами. :D
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Составление запроса

Сообщение yiiliveext »

Код: Выделить всё

SELECT * FROM order JOIN contract ON contract.id = (SELECT id FROM contract WHERE contract.order_id = order.id LIMIT 1) 
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Составление запроса

Сообщение unknownby »

Долго выполняется :(

Код: Выделить всё

Task::find()
            ->select(Task::TABLE_ALIAS . '.*, taskcontracts_id')
            ->from([Task::TABLE_ALIAS => Task::tableName()])
            ->joinWith(['taskContractOne' => function ($query) {
                    $query->select(['taskcontracts_id'])->limit(1);
                },
            ], false, 'LEFT JOIN')
            ;
Связи пробовал разные

Код: Выделить всё

    public function getTaskContract(){
        return $this->hasMany(TaskContract::className(), ['task_id' => 'task_id'])->from([TaskContract::TABLE_ALIAS => TaskContract::tableName()]);
    }

    public function getTaskContractOne(){
        return $this->hasOne(TaskContract::className(), ['task_id' => 'task_id'])->from([TaskContract::TABLE_ALIAS => TaskContract::tableName()]);
    }
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Составление запроса

Сообщение yiiliveext »

Индексы есть? Покажите план запроса.
Вы все 40к записей за раз выбираете?
И запрос неправильно записан в билдере.
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Составление запроса

Сообщение unknownby »

yiiliveext писал(а): 2019.11.28, 11:20 Индексы есть? Покажите план запроса.
Вы все 40к записей за раз выбираете?
И запрос неправильно записан в билдере.
Благодарю :D Запрос исправил на упрощенную версию и индексы прописал.
В проекте используются индексы, но в данной таблице не сделано было. :D
А вообще выборка идет всех сразу записей и потом подготавливаются данные под аналитику и запихиваются в JqxGridWidget

Пихать индексирование во все таблицы не ухудшид ли работу с выборками?
yiiliveext
Сообщения: 910
Зарегистрирован: 2019.08.13, 01:49

Re: Составление запроса

Сообщение yiiliveext »

Не ухудшит. Для аналитики и статистики используйте кеширование уже обработанных данных, если они не меняются. К ним добавляйте свежие и формируйте отчет.
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Составление запроса

Сообщение unknownby »

yiiliveext писал(а): 2019.11.28, 11:48 Не ухудшит. Для аналитики и статистики используйте кеширование уже обработанных данных, если они не меняются. К ним добавляйте свежие и формируйте отчет.
На сервере происходит кеширование запросов, а в самой аналитике происходит выгрузка и работа ведется уже только с теми данными, которые выгружены. Спасибо за помощь :D
Ответить