添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
2021-07-26 15:33:16 分类:技术学堂

近期优化了一个响应速度比较慢的 Laravel 项目接口,经过一顿排查,最终发现有几处代码执行时间较慢,其中一处代码大致如下:

$keys = Model::query()

->where(...) // 中间一些查询条件省去

->pluck('id')

->toArray();

这段看起来平平无奇的代码执行起来居然要 400-500 毫秒!!然后我打印了查询出来的行数 count($keys),发现查出的数据大概在 1 万条以上时响应时间就会有明显的加长。出现这个问题我的第一反应是数据库查询响应太慢,但是看了 sql 日志却发现数据查询响应时间只要二三十毫秒,这跟想象的完全不一样,难道 laravel 真的有这么不堪吗?


然后我想了下,也许是因为查出数据后实例化 Model 导致的问题? 于是我利用了 Builder::macro() 扩展了一个 cursorPluck 方法,省去查出数据后 new Model 的步骤,代码大概如下

use Illuminate\Database\Eloquent\Builder;


Builder::macro('cursorPluck', function ($value, $key = null) {

/* @var \Illuminate\Database\Eloquent\Collection $results */

$results = $this->model->newCollection();


$this->select(array_values(array_unique(array_filter([$value, $key]))));


// 这里直接使用 Illuminate\Database\Query\Builder::cursor() 方法,可以省去实例化 Model 这一步骤

foreach ($this->applyScopes()->query->cursor() as $record) {

$record = is_array($record) ? $record : (array) $record;


if ($key) {

$results->put(($record[$key] ?? null), ($record[$value] ?? null));

} else {

$results->add(($record[$value] ?? null));

}

}


return $results;

});


// 然后上述代码更改为

$keys = Model::query()

->where(...)

->cursorPluck('id')

->toArray();

更换了上述代码之后效果立竿见影,速度快了许多!代码执行由开始的 400-500 毫秒下降到 100 毫秒左右。




  • 企业光伏数据对接碳达峰系统
  • Laravel artisan 写入日志的用户和 fpm 不一致,导致无法写入日志问题
  • git提交大文件报错remote: error: GH001: Large files detected. You may want to try Git Large File Storag
  • 关于Laravel model查询返回大量数据的性能优化
  • laravel配置不同环境的配置文件
  • laravel 8 修改默认的paginate分页模板方法
  • git命令大全_git命令基本用法
  • 微信公众号H5如何跳转小程序?
  • 小程序wx.previewImage查看图片再次点击返回时重新加载页面问题
  • carbon获取上个月第一天和最后一天
  • 分销小程序 小程序三级分销商城系统
  • 小程序ios虚拟支付问题
  •