文章转发自专业的Laravel开发者社区,原文链接:https://learnku.com/laravel/t...如果你一直关注我的作品,你就会知道我我支持将Laravel应用程序中的更多工作转移到数据库层。通过在数据库层做更多的工作,我们通常可以减少我们进行数据库查询的次数,减少应用程序使用的内存量,并减少Eloquent处理模型所花费的时间。这可以带来一些相当显着的性能提升。将更多工作推到数据库层的一个好方法是使用子查询。子查询允许您在另一个数据库查询中运行嵌套查询。当无法通过关系查询找到结果时,这是一种无需执行任何额外数据库查询即可获取辅助模型数据的强大方法。您还可以使用orderby语句、where语句和其他数据库子句进行子查询。在LaraconUS2019演讲中,我引用了我正在使用的查询构建器,这使我们更容易在Laravel中使用子查询。我已经向laravel提交了三个PR,以将它们添加到laravel的核心。概述:“选择”子查询拉取请求#29567select()和addSelect()查询构建器方法支持子查询例如,假设我们有一个目的地表和飞往目的地的航班表。flights表包含一个arrival_at字段,指示航班何时到达目的地。在Laravel6.0中,使用了一个新的子查询功能。例如,要查询所有目的地和到每个目的地的最后一班航班的名称,我们可以使用一条语句来查询:returnDestination::addSelect(['last_flight'=>Flight::select('name')->whereColumn('destination_id','destinations.id')->orderBy('arrived_at','desc')->limit(1)])->get();注意这里是如何使用Eloquent来生成子查询的。这种语法更好,更具表现力。同样,您也可以使用查询生成器:returnDestination::addSelect(['last_flight'=>function($query){$query->select('name')->from('flights')->whereColumn('destination_id','destinations.id')->orderBy('arrived_at','desc')->limit(1);}])->get();“Orderby”子查询此外,Pullrequest#29563允许我们在查询生成器的orderBy()方法中使用子查询。继续上面的示例,我们可以根据最后一班航班到达目的地的时间对目的地进行排序。返回Destination::orderByDesc(Flight::select('arrived_at')->whereColumn('destination_id','destinations.id')->orderBy('arrived_at','desc')->limit(1))->得到();与select一样,您也可以直接使用查询构建器来创建子查询。例如,您可能希望根据用户的上次登录日期进行排序:returnUser::orderBy(function($query){$query->select('created_at')->from('logins')->whereColumn('user_id','users.id')->latest()->limit(1);})->get();“From”子查询最后,Pullrequest#29602使我们的from()在查询构建器中可以使用子查询。这些有时称为派生表。例如,您可能想要计算应用程序中用户的平均捐赠总额。然而,嵌套的聚合函数在SQL中是不可能的:AVG(SUM(amount))相反,我们可以使用一个from子查询来计算它:returnDB::table(function($query){$query->selectRaw('sum(金额)作为总计')->from('donations')->groupBy('user_id');},'donations')->avg('total');您可能不需要每天都使用它,但是当您确实需要它时,它是必不可少的。如果你在Laravel之外使用Eloquent,需要注意的一个重大变化是Illuminate/Database/Capsule/Manager对象上的table()方法的明显变化。它从tabletable($table,$connection=null)变成了tabletable($table,$as=null,$connection=null)。了解更多如果您有兴趣了解有关子查询和其他高级数据库技术的更多信息,请务必关注我的博客并观看我的LaraconUS2019演讲。在Laracon,我还发布了一个新的视频课程,我正在研究Eloquent的性能模式。本课程的目的是教Laravel开发人员如何通过将更多工作推到数据库层来大幅提高Laravel应用程序的性能,同时仍然使用EloquentORM。如果您有兴趣,请务必加入邮件列表!
