Простой запрос Eloquent занимает слишком много времени для выполнения

У меня 2 запроса. Несмотря на то, что первый более сложный и извлекает гораздо больше данных, его выполнение занимает всего 154 мс, в то время как выполнение второго занимает 1,76 с.

Первый (выполняется быстро):

$offers = Offer::select(\DB::raw('tbl_offer.offer_id as sys_id, 
                                  tbl_offer.offer_name, 
                                  tbl_offer.preview_url, 
                                  COALESCE(tbl_offer.is_allow_website_links, 
                                  false) as is_allow_website_links, 
                                  tbl_offer.is_require_approval, 
                                 tbl_relationship.fk_relationship_status_id, 
                                  tbl_offer.is_private,
                                  tbl_offer.currency'))
                        ->leftJoin('tbl_relationship', function ($q) use ($affiliateId) {

                        $q->on('tbl_offer.offer_id', '=', 'tbl_relationship.fk_offer_id')
                          ->where('tbl_relationship.fk_affiliate_id', '=', $affiliateId);})
                          ->whereIn('fk_offer_status_id', [ 18, 19 ])
                          ->where('is_display', 1)
                          ->where('tbl_offer.is_trd_deleted', 0)
                          ->orderBy('offer_name')
                          ->get();

Второй (выполняется медленно):

$currencies = Currency::select(\DB::raw('DISTINCT currency_code_from AS currency'))
                 ->where('sys_name', 'openexchangerates')
                 ->orderBy('currency')
                 ->get();   
  1. В чем может быть проблема?
  2. У вас есть идеи, как уменьшить время загрузки?
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
5
0
1 330
3

Ответы 3

прежде всего вы используете 2 запроса в один.

Это первый запрос:

$currencies = Currency::where('sys_name', 'openexchangerates')
            ->orderBy('currency')
            ->get();  

А это еще один:

\DB::raw('DISTINCT currency_code_from AS currency')

Чтобы использовать оба запроса в одном, вы должны использовать это:

$currencies = Currency::selectRaw('DISTINCT currency_code_from AS currency')
            ->where('sys_name', 'openexchangerates')
            ->orderBy('currency')
            ->get();   

Я надеюсь, что таким образом сократится время выполнения.

Спасибо за ваше предложение, определенно хороший аргумент. Однако в моем случае это сократило время загрузки всего на 0,04 с. На этот раз я решил проблему с помощью некоторого «обходного пути». Поскольку курс валюты меняется каждый день для каждой доступной валюты, я просто получаю самый большой currency_rate_batch_id и все валюты, связанные с этим идентификатором (позволяет мне быстро получить все отдельные валюты). Однако я буду применять индексацию (как предложил @Josh) и избегать двойных запросов на протяжении всего проекта.

Adel Maratova 16.11.2018 09:32

Как сказал @Nikolas, переход с select(DB::raw.. на selectRaw(... поможет со скоростью.

Еще одна вещь, которую вы захотите проверить, - это индексирование основных столбцов вашей таблицы.

Я предполагаю, что вы используете Mysql, поэтому посмотрите следующие документы по индексации

https://dev.mysql.com/doc/refman/5.5/en/optimization-indexes.html

Наличие индексов по ключевым столбцам таблиц может существенно повлиять на скорость выполнения запросов.

Подробную информацию о добавлении индексов посредством миграции в Документах можно найти здесь:

https://laravel.com/docs/5.5/migrations#indexes

Спасибо за предложение. На этот раз я решил проблему с помощью некоторого «обходного пути». Поскольку курс валюты меняется каждый день для каждой доступной валюты, я просто получаю самый большой currency_rate_batch_id и все валюты, связанные с этим идентификатором (позволяет мне быстро получить все отдельные валюты). Однако я буду применять индексацию и избегать двойных запросов на протяжении всего проекта, чтобы в целом сократить время загрузки.

Adel Maratova 16.11.2018 09:34

Просто оставьте этот ответ, так как он может быть полезен для людей, которые уже пробовали применять индексацию и оптимизацию запросов, но не смогли значительно сократить время.

Мне удалось сократить время загрузки запроса с 1,76 с до 0,127 с.

Я решил проблему, используя "обходной путь". Поскольку курс валюты меняется каждый день для каждой доступной валюты, я просто получаю самый большой currency_rate_batch_id и все валюты, связанные с этим идентификатором (позволяет мне быстро получить все отдельные валюты).

Однако я буду применять индексацию (как предложил @Josh) и избегать двойных запросов на протяжении всего проекта (как предлагает @Nicolas).

Другие вопросы по теме