Как ускорить запрос при groupBy?

Ссылка скопирована
1 ответ

Как можно ускорить выборку? Записей очень много

$rows->get()->groupBy(function ($item) {                     return sprintf(                         '%s by %s',                         $item->created_at->format('Y-m-d H:i:s'),                         is_null($item->user) ? 'undefined' : $item->user->getNameAttribute()                     );                 }             )->paginate($paginate);

$rows->get()->groupBy(function ($item) { return sprintf( '%s by %s', $item->created_at->format('Y-m-d H:i:s'), is_null($item->user) ? 'undefined' : $item->user->getNameAttribute() ); } )->paginate($paginate);

Результат моей выбоки

Как ускорить запрос при groupBy?

Дополнительно:

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

  • не получать всю коллекцию
  • Максим Федоров,
    1.Запрос до группировки коллекции
    select `revisions`.`id` as `id`, `revisionable_id`, `user_id`, `old_value`, `new_value`, `revision_keys`.`name` as `field_name`, `revision_types`.`name` as `model_name`, `created_at` from `revisions` inner join `revision_keys` on `revisions`.`revision_key_id` = `revision_keys`.`id` inner join `revision_types` on `revisions`.`revision_type_id` = `revision_types`.`id` where `revisionable_id` in (?) and `revision_types`.`name` = ? order by `revisions`.`id` desc

    select `revisions`.`id` as `id`, `revisionable_id`, `user_id`, `old_value`, `new_value`, `revision_keys`.`name` as `field_name`, `revision_types`.`name` as `model_name`, `created_at` from `revisions` inner join `revision_keys` on `revisions`.`revision_key_id` = `revision_keys`.`id` inner join `revision_types` on `revisions`.`revision_type_id` = `revision_types`.`id` where `revisionable_id` in (?) and `revision_types`.`name` = ? order by `revisions`.`id` desc

    2. Индексы (revisions_created_at_index,revisions_revision_key_id_foreign,user_id)

  • jazzus, Пробовал chunk использовать но такой же результат не получилось получить как на скрине
  • kaxa3201, у вас выборка идет не по индексам

    выполните explain

    кроме того inner join — декартово произведение, лучше сделайте outer (left/right) join

    или разбейте запросы на несколько быстрых и выбирайте по индексу записи

  • Максим Федоров, просто самая тяжелая и долгая обработка выполняется обход коллекции, можно ли эту часть ускорить?
  • kaxa3201, а зачем ты сначала получаешь все записи, а потом делаешь по ним делаешь группировку и пагинацию?
  • Максим Федоров, left и right join никак не улучшат текущий inner join
  • Если это прям постоянно нужно, то можно провести денормализацию: добавить модель-таблицу со значением группировки (return sprintf(
    '%s by %s',
    $item->created_at->format('Y-m-d H:i:s'),
    is_null($item->user) ? 'undefined' : $item->user->getNameAttribute()
    ); и вот это всё), и поле в исходной таблицы с её id, сделать по значению группировки индекс, получать только нужные значения группировки из этой таблицы, а затем после получения страницы уже получать туда нужные данные исходной таблицы, например через https://laravel.com/docs/8.x/eloquent-relationship...

    • Кстати я пробовал accessor добавить и запрос стал дольше на пару секунд…
    • kaxa3201, я не про изменение текущего запроса, а про изменение структуры БД, дополнительно одна таблица и одна колонка, которые драматически ускорят выборку. Не надо будет читать всю таблицу с огромным количеством строк и большим количеством колонок, надо будет читать только таблицу с двумя колонками, и то не целиком + не целиком, а по индексу читать кусок "большой" таблицы. если чтение происходит чаще (а судя по всему оно происходит чаще), то суммарный выигрыш будет сильно больше, чем увеличение задержки при записи.

    Ответы:

    Вы путаете запрос к базе и работу с коллекцией.
    $rows->get() - вернула вам уже кучу мусора, а дальше вы с ней работаете на стороне php. Делайте группировку на стороне ДБ средствами sql
    $rows->groupBy(...)->get()

    Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Анна SEO Ответ

    Для ускорения запроса при использовании оператора groupBy в SQL, можно применить несколько методов оптимизации:

    1. Индексы: убедитесь, что у вас есть правильные индексы на столбцы, по которым вы группируете данные. Использование индексов может значительно ускорить выполнение запроса.

    2. Оптимизация запроса: избегайте лишних операций и фильтров. Попробуйте оптимизировать запрос, чтобы избежать лишних операций соединения и фильтрации данных.

    3. Использование агрегатных функций: если возможно, используйте агрегатные функции вместо оператора groupBy. Например, вместо запроса с groupBy можно написать запрос с использованием функций SUM(), COUNT() и т.д.

    4. Предварительная агрегация: если у вас есть возможность, предварительно агрегируйте данные перед выполнением оператора groupBy. Это может существенно сократить объем данных, с которыми нужно работать.

    Пример использования индексов для ускорения запроса с оператором groupBy в SQL (например, на языке PHP):

    CREATE INDEX idx_column_name ON table_name (column_name);

    CREATE INDEX idx_column_name ON table_name (column_name);

    Эти методы помогут вам ускорить выполнение запросов с оператором groupBy и повысить производительность вашей базы данных.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно