在Laravel 5.4中从数据库加载数据的最有效方法是什么?

时间:2017-06-15 17:49:23

标签: sql postgresql laravel-5 query-optimization

我的数据库中有这些表(PostgreSQL):

events(id, title, starts_at, ends_at, ...)
reservations(id, event_id, ...)
reservation_messages(id, reservation_id, ...)

我有API调用:/api/v1/host/events必须返回json事件数组,但数组中的每个json对象必须包含两个额外的字段reservations_countunread_messages_count。此外,我只需要尚未结束的事件,这意味着ends_at列大于now()

我正在考虑加载这些“计数”字段的最有效方法。 下一个查询给出了我想要的结果,但我不知道它的效率如何:

$user->host->events()
    ->where('ends_at', '>', Carbon::now())
    ->withCount([
        'reservations', 
        'reservationMessages AS unread_messages' => function($query) { 
            $query->where('seen', false); 
        }
    ])
    ->get()

这将产生大的查询,并且会有很多连接:

select "events".*, (select count(*) from "reservations" where "events"."id" = "reservations"."event_id") as "reservations_count", (select count(*) from "reservation_messages" inner join "reservations" on "reservations"."id" = "reservation_messages"."reservation_id" where "events"."id" = "reservations"."event_id" and "seen" = ?) as "unread_messages_count" from "events" where "events"."host_id" = ? and ("events"."host_id") is not null and "ends_at" > ? and ("events"."deleted_at") is null

是否有更有效的方法来加载所需的结果,因为我认为这个查询在包含大量数据的数据库上会非常慢?

1 个答案:

答案 0 :(得分:0)

您可以在关系之间使用with()将查询链接在一起,以便快速加载。如果您关注数据库大小和执行时间,只需在集合中检索记录后计算记录,并附加一个动态属性,其中包含预留计数和一个未读消息。在内存中处理集合很快,并且可以省去数据库查询。

相关问题