【问题标题】:Laravel eloquont query takes long time to fetch dataLaravel 雄辩的查询需要很长时间才能获取数据
【发布时间】:2021-06-11 18:09:58
【问题描述】:

我有一个查询只是为了检索数据,当我尝试从下面的查询中获取 10k 数据时,它需要超过 1.7 分钟。这是合理的,或者这次我该如何改进。

Vehicles::leftJoin('vehicle_details', 'vehicle_details.id', 'vehicles.vehi_details_id')
        ->leftJoin('vehicle_extras', 'vehicle_extras.vehicle_id','vehicles.id')
        ->leftJoin('reasons', 'reasons.vehicle_id', 'vehicles.id')
        ->leftJoin('revised_vehicles', 'revised_vehicles.vehicle_id','vehicles.id')
        ->leftJoin('makes', 'makes.model_id', 'vehicle_details.model_id')
        ->leftJoin('bidder_invoices', 'bidder_invoices.vehicle_id', '=', 'vehicles.id')
        ->leftJoin('bidding_views', 'bidding_views.vehicle_id', '=', 'vehicles.id')
        ->leftJoin('bidder_prs', 'bidder_prs.vehicle_id', '=', 'vehicles.id')
        ->leftJoin('bidder_remarks', 'bidder_remarks.vehicle_id', '=', 'vehicles.id')
        ->leftJoin('vehicle_pins', 'vehicle_pins.vehicle_id', '=', 'vehicles.id')
        ->leftJoin('translations', 'translations.vehicle_id', '=', 'vehicles.id')          
        ->where(function ($query) {
            $query->where('vehicles.approve', '=', 1)
                ->orWhereNull('vehicles.approve');
        })
        ->orderBy('vehicles.site', 'ASC')
        ->orderBy('vehicles.auc_time', 'ASC')
        ->select([
            'vehicles.*',
            'vehicle_details.color as vehi_color',
            'vehicle_details.grade as vehi_grade',
            'vehicle_details.images',
            'makes.model_name',
            'vehicle_extras.id as extra_details_id',
            'vehicle_extras.ic_remarks',
            'vehicle_extras.bidder_adj',
            'reasons.fob_issue',
            'reasons.fob_approve',
            'reasons.decline_remark',
            'reasons.tc_issue',
            'reasons.fob_overruling_remark',
            'bidder_invoices.invoice_name',
            'bidding_views.reason as bidder_reason',
            'bidder_prs.bidder_mb as bidder_mb',
            'bidder_remarks.bidder_remarks as bidder_remarks_daily',
            'revised_vehicles.old_mb_round',
            'translations.assigned_translator'
        ])
        ->paginate(10000);

我还为每个连接列添加了索引。我也使用 MySQL 作为我的数据库

【问题讨论】:

  • 在不知道您的架构或 dbms(mysql 或 postgres)的情况下很难说。能否提供上述查询的查询计划?
  • @Matthew 我用过 MySQL,我会用细节更新问题
  • 另外,您正在对10.000 结果进行分页...永远不要这样做,大量内存,只有这样会花费很多时间...即使浏览器也很难尝试显示10k 个结果...
  • @matiaslauriti 对于 OP 应如何构建查询以实现他们正在寻找的结果,您有任何具体的建议或资源吗?由于 OP 没有提及他们使用数据的原因,因此无法知道 10,000 条记录的结果集是否存在问题,或者是否有更有效的方式来构建程序。
  • @Matthew 我没有,只有经验...... OP 可以做他想做的任何事,毫无疑问,看到很多 SO 帖子的生产应用程序代码非常糟糕,这令人沮丧。 ..我知道这不是一个教程页面,但令人愤怒......你有 Eloquent 的魔力,人们会创建怪物查询......绝对疯狂......

标签: laravel eloquent laravel-8


【解决方案1】:

你可以在你的 Eloquent 模型类中使用 Eloquent 关系作为方法参考 Eloquent Relationship 如果关系是 1:1 使用 hasOne 如果关系是 1:M 使用 has Many 如果关系是 M:1,则使用属于

在您的车辆模型中

例如

1:1


public function vehicleDetails() {
    return $this->hasOne(VehicleDetail::class,'vehi_details_id','id');
}

1:M


public function VehicleExtras() {
    return $this->hasMany(VehicleExtras::class,'id','vehicle_id');
}

对于 M:1


public function VehicleMakes() {
    return $this->belongsTo(VehicleMakes::class,'model_id','model_id');
}

在建立所有关系后,您可以使用过滤器获取车辆表,如下所示


$data['vehicles'] = Vehicles::whereNull('vehicles.deleted_at')
        ->where(function ($query) {
            $query->where('vehicles.multiple_po', 0)
                ->orWhereNull('vehicles.multiple_po');
        })
        ->where(function ($query) {
            $query->where('vehicles.approve', '=', 1)
                ->orWhereNull('vehicles.approve');
        })
        ->orderBy('vehicles.site', 'ASC')
        ->orderBy('vehicles.auc_time', 'ASC')
        ->paginate(10000);

那么,

你可以像往常一样将刀片中的车辆和如果你需要调用关系表属于某个id,

要从车辆详细信息中获取描述,您可以访问如下


$data['vehicles']->vehicleDetails->description 

或从品牌表中获取车辆的品牌


$data['vehicles']->VehicleMakes->name

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-25
    • 2018-07-06
    • 1970-01-01
    • 2019-12-20
    • 2016-04-22
    • 2016-06-17
    • 2021-06-15
    • 2011-01-17
    相关资源
    最近更新 更多