给 Laravel 项目安装了 debugbar 调试工具,在 debug 模式下打开页面底部会出现一个工具条,点开可以查看各项性能统计,最重要的是打印页面执行的 sql 语句和调试内容。下面利用 debugbar 工具找到一个 sql 查询的优化点。
优化页面 sql 查询
这里有两个模型,目的地模型和游记模型,他们是一对多的关系,在目的地模型 Destination.php 的 Model 中关系定义如下:
PHP
/**
* 定义目的地-游记的一对多关系
* @return IlluminateDatabaseEloquentRelationsHasMany
*/
public function travel()
{
return $this->hasMany(Travel::class, 'destination_id');
}
为了统计每个目的地下有多少篇游记,用到了 Laravel 模型很好用的一个特性 appends,定义 appends 数组就是自定义了表字段:
PHP
/**
* 自定义字段
* @var array
*/
protected $appends = [
'url',
'first_travel_url',
'total',
];
这里 total 指的就是目的地下一共有多少篇游记,优化前的代码是这样的:
/**
* 目的地游记数
* @return mixed
*/
public function getTotalAttribute()
{
return $this->travel()->count();
}
这样就导致遍历目的地查询游记的总数,增加 sql 语句频次。这本来是个很好的特性,但是如果要额外查询数据库可能会增加查询开销。debugbar 工具在页面上打印了该页面执行的所有 sql 语句,如图:
显然这里需要进行优化,需要用 group by 目的地的方式统计,只需要一条 sql 语句就可以了。
Laravel 中使用
用 group by 进行统计
在游记模型 Travel.php 的 Model 中增加一个方法:
/**
* 获取每个目的地的游记总数
* @return array
*/
public function getTravelNumsGroupByDestination()
{
$travelNums = [];
$result = $this->groupBy('destination_id')->get(['destination_id', DB::raw('count(*) as total')]);
foreach ($result as $item) {
$travelNums[$item->destination_id] = $item->total;
}
return $travelNums;
}
这里 $result 返回的是一个 Collection 对象,里面是 Travel 类的集合,实际上执行的 sql 语句是:select destination_id, count(*) as total from travel group by destination_id
group-by-select-count
在页面控制器 TravelController.php 的 index 方法中调用这个方法,然后赋值给模板即可。
PHP
/**
* 游记首页
* @return IlluminateContractsViewFactory|IlluminateViewView
*/
public function index()
{
$data = Cache::remember('travel.index', self::CACHE_TIME, function () {
$destinationList = $this->destination->getList(12);
$travelList = $this->travel->latest('begin_date')->take(12)->get();
$travelNums = $this->travel->getTravelNumsGroupByDestination();
return [
'destinationList' => $destinationList,
'travelList' => $travelList,
'travelNums' => $travelNums
];
});
return view('travel.index', $data);
}
这里把数据库的相关查询结果进行了缓存,只有在缓存过期会查询数据库。
在模板中做出相应的修改后,就完成了这个 sql 的性能优化,如果查询多的话这可以减少大量的 sql 查询。
优化后页面执行 sql 的情况:
通过 debugbar 工具可以很好的掌握各项性能,不仅如此,他是个很好的调试工具,我们可以通过打印 log 的方式调试代码,也可以用 debugbar 提供的调试方法打印内容,很方便,使用 Laravel 开发必备的调试工具。
创造与魔法 安卓版v1.0.0750
创造与魔法是一款开放世界手游,在游戏中玩家可探索这个奇妙的世
创造与魔法修改版 最新版v1.0.0750
创造与魔法无限点券版是款探索冒险游戏,该款游戏的操作还是蛮自
战争与文明官方版本 安卓版v1.7.16
战争与文明是一款由上海邮通科技有限公司开发的战争策略游戏,这
迷你世界0元领皮肤无限迷你币版 最新安卓版v1.43.0
迷你世界0元购买皮肤版是这款开放沙盒冒险建造游戏的特殊破解版
创造与魔法无限经验版 安卓版v1.0.0750
创造与魔法无限经验版是款可以改造环境,整个游戏的自由度还是蛮