首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Laravel在带有加载关系的简单分页查询上检索太多的模型。

Laravel在带有加载关系的简单分页查询上检索太多的模型。
EN

Stack Overflow用户
提问于 2019-08-21 18:42:31
回答 1查看 555关注 0票数 0

我有一个简单的数据库,有两个表。orders -主表,关于16_000记录。每个订单都有付款。order_payments表是关于17_000记录的。另外,每个order_tourists表- 33_000行中都可以有零个或更多的旅行者。

订单模型如下所示

代码语言:javascript
复制
namespace App;

class Order extends \Illuminate\Database\Eloquent\Model
{
    public function payments()
    {
        return $this->hasMany('App\OrderPayment');
    }

    public function tourists()
    {
        return $this->hasMany('App\OrderTourist');
    }
}

我有一个简单的任务来显示所有订单的分页列表。此列表中的每一项都应显示某些订单的信息(来自orders表)、所有支付的总和和所有旅行者的姓名。

我想到的第一件事是这样的。

获取支付和旅行者的所有订单,并将这些数据传递给视图。

代码语言:javascript
复制
Route::get('search_offers', static function () {
    $orders = \App\Order::query()->with(['payments', 'tourists']);

    return view('orders', [
        'orders' => $orders->paginate(),
    ]);
});

我的orders.blade.php很简单

代码语言:javascript
复制
<ol>
    @foreach($orders as $order)
    <li>
        {{$order->request_id}}; {{ $order->payments->sum('amount') }}; {{ $order->tourists->implode('fullName', ', ') }}
    </li>
    @endforeach
</ol>

但是,即使是查询的数量也很小--我对模型有很多操作。我添加了一个自定义钩子来跟踪所有雄辩的事件。*在第一种情况下,这类事件的23_000更多。

然后,我试图删除关系的加载,因此,对于每一个订单,Laravel必须运行一个单独的查询,以获得所有订单的付款和旅行者。我只是在我的控制器里这么做了

代码语言:javascript
复制
return view('orders', [
    'orders' => \App\Order::query()->paginate(),
]);

因此,我得到了更多的查询,但是页面速度有所提高,一些受影响的模型明显减少。

为了跟踪受影响的模型,我在AppServiceProvider::boot方法中添加了一个listner,并在一个调试器面板中输出了AppServiceProvider::$水合模型的值

代码语言:javascript
复制
Event::listen('eloquent.*', static function ($event) {
    if (strpos($event, 'eloquent.retrieved') !== false) {
        AppServiceProvider::$hydratedModels++;
    }
});

所以,我的问题是,即使我只显示了15项,怎么可能检索到这么多模型。看起来,Laravel以某种方式将它们全部处理,但只对所需的页面进行了回放。

现在,运行额外的查询来获取一些数据并不是什么大事,但我想知道,也许我做错了什么,也有可能加载关系,但不会导致Laravel检索所有模型。

EN

回答 1

Stack Overflow用户

发布于 2019-08-22 06:29:51

我发现了问题。谢谢,@dparoli,谢谢你的建议。

我的模型有一个主键作为UUID。但是我没有改变Model::$keyType,所以在内部Laravel将它转换成一个整数,查询如下所示。

我得到的不是UUID字符串,而是用于相关记录的整数作为order_id。

因此,我添加了protected $keyType = 'string'; ,一切都按预期开始工作。

PS。不过,我想知道它以前是怎么工作的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57597554

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档