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

У appointment может быть много статусов, но последним созданным отношением между appointment и status является текущий статус встречи. В моей таблице данных о встречах я хочу отобразить соответствующего агента, InstructionType, SignUpCustomer и последний status. Я хочу paginate этих записей по 10 на страницу.

Соответствующие модели:

  1. Appointment ( belongsTo agent, instruction_type and sign_up_customer, belongsToMany status)
  2. Agent
  3. InstructionType
  4. SignUpCustomer

У меня есть этот запрос в моем контроллере, который дает результат, который я отправляю в Datatables.

$query = Appointment::with(['agent', 'instruction_type', 'sign_up_customer']);
            $query->with(['statuses' => function ($query) {
                $query->latest()->first();
            }]);
            $table = Datatables::of($query);

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

select `statuses`.*, `appointment_status`.`appointment_id` as `pivot_appointment_id`, `appointment_status`.`status_id` as `pivot_status_id`, `appointment_status`.`created_at` as `pivot_created_at`, `appointment_status`.`updated_at` as `pivot_updated_at` from `statuses` inner join `appointment_status` on `statuses`.`id` = `appointment_status`.`status_id` where `appointment_status`.`appointment_id` in ('2') order by `created_at` desc limit 1

select `statuses`.*, `appointment_status`.`appointment_id` as `pivot_appointment_id`, `appointment_status`.`status_id` as `pivot_status_id`, `appointment_status`.`created_at` as `pivot_created_at`, `appointment_status`.`updated_at` as `pivot_updated_at`, `appointment_status`.`appointment_id` as `pivot_appointment_id`, `appointment_status`.`status_id` as `pivot_status_id`, `appointment_status`.`created_at` as `pivot_created_at`, `appointment_status`.`updated_at` as `pivot_updated_at` from `statuses` inner join `appointment_status` on `statuses`.`id` = `appointment_status`.`status_id` where `appointment_status`.`appointment_id` in ('2') order by `created_at` desc limit 1

Я также пробовал это:

Модель:

/**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
     */
    public function statuses()
    {
        return $this->belongsToMany(Status::class, 'appointment_status')->withTimestamps();
    }

    public function latestStatus()
    {
        return $this->statuses()->latest()->first();
    }

Контроллер:

$query = Appointment::with(['agent', 'instruction_type', 'sign_up_customer', 'latestStatus']);
            $table = Datatables::of($query);

Но я получаю эту ошибку: BadMethodCallException в строке Builder.php 2445: вызов неопределенного метода Illuminate\Database\Query\Builder::addEagerConstraints()


person showFocus    schedule 31.03.2017    source источник
comment
Пожалуйста, опишите, как выглядят ваши столы, что вы хотите получить и что вы пробовали. stackoverflow.com/help/how-to-ask   -  person Indra    schedule 31.03.2017
comment
Удаление $query-›paginate(10) уменьшает запрос до 8. Однако у меня все еще есть два оператора в последних строках выше ^   -  person showFocus    schedule 31.03.2017
comment
Если вам нужна производительность, вы должны использовать операторы RAW. Eloquent не предназначен для производительности.   -  person Alex Slipknot    schedule 31.03.2017
comment
Очевидно, что удаление последнего оператора сверху повысит производительность. Однако я просто ищу способ удалить последнее утверждение, поскольку оно не требуется.   -  person showFocus    schedule 31.03.2017


Ответы (1)


Вы не можете сделать это, используя локальную область? https://laravel.com/docs/5.4/eloquent#local-scopes

public function scopeLatest($query)
{
    return $query->orderBy('created_at', 'DESC')->offset(0)->limit(1);
}

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

person Joe    schedule 31.03.2017
comment
Я думаю, что ваш ответ немного неуместен. Вопрос в том, как оптимизировать SQL-запрос. Не представление кода - person Alex Slipknot; 31.03.2017
comment
Спасибо за ваше мнение. - person Joe; 31.03.2017