侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Laravel Eloquent orm的性能 - N+1 查询问题

Laravel  /  管理员 发布于 2个月前   106

我知道这个问题 N+1 是影响我项目性能的问题之一,我发现这篇文章包含了原因 

https://laravel-news.com/laravel-n1-query-problems 

和解决方案 问题,我想和你分享,因为这个话题很重要

四个案例明确问题并解决问题


案例 1.“常规”N+1 查询

// app/Models/Book.php
class Book extends Model
{
    public function author()
    {
        return $this->belongsTo(Author::class);
    }
}
// Then, in some Controller:
$books = Book::all();
foreach ($books as $book) {
    echo $book->author->name;
}

固定

// Instead of
$books = Book::all();
// You should do
$books = Book::with('author')->get();


案例 2. 两个重要符号

public function index()
{
    $authors = Author::with('books')->get();
    return view('authors.index', compact('authors'));
}
// Blade
@foreach($authors as $author)
    <tr>
        <td>{{ $author->name }}</td>
        <td>{{ $author->books()->count() }}</td>
    </tr>
@endforeach

因此,关系方法将为每个作者查询数据库。 但是如果你加载数据,不带 () 符号,它会成功使用急切加载的数据 $author->books

使固定

// Controller
$authors = Author::withCount('books')->get();
// Blade
{{ $author->books_count }}


案例 3. Accessor 中的“隐藏”关系

// Controller
public function index()
{
    $authors = Author::all();
    return view('authors.index', compact('authors'));
}
// Blade
@foreach($authors as $author)
    <tr>
        <td>{{ $author->name }}</td>
        <td>{{ $author->is_active ? 'Yes' : 'No' }}</td>
    </tr>
@endforeach
“is_active”是在 Eloquent 模型中定义的
use Illuminate\Database\Eloquent\Casts\Attribute;
class Author extends Model
{
    public function isActive(): Attribute
    {
        return Attribute::make(
            get: fn () => $this->books->count() > 0,
        );
    }
}


案例 4. 小心 with Packages

Laravel 有一个很棒的软件包生态系统,但有时“盲目地”使用它们的功能是很危险的。 如果您不小心,您可能会遇到意外的 N+1 查询。

针对 N+1 查询的内置解决方案

从 Laravel 8.43 开始,框架 

https://laravel-news.com/disable-eloquent-lazy-loading-during-development

除了 Laravel Debugbar 进行检查,还可以添加代码来预防这个问题

需要在 

app/Providers/AppServiceProvider.php 

添加两行代码

use Illuminate\Database\Eloquent\Model;
class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Model::preventLazyLoading(! app()->isProduction());
    }
}

现在,如果您启动任何包含 N+1 查询问题的页面,您将看到一个错误页面

我只解释了重点,但要深入,必须增加文章并从中受益。


转:

https://dev.to/morcosgad/eloquent-performance-n1-query-problems-laravel-5ahj

  • 上一条:
    go语言WaitGroup中使用协程嵌套示例代码
    下一条:
    php语言中按字节为单位获取JSON数据大小
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Laravel 9.24版本发布(0个评论)
    • Laravel collect集合中获取二维数组中键值功能示例代码(0个评论)
    • lumen中验证类的实现及使用流程步骤(0个评论)
    • 构建你自己的Laravel扩展包的流程步骤(0个评论)
    • Laravel 9.23版本发布(0个评论)
    • 近期文章
    • GnuPG(GPG)生成用于替代SSH密钥的子密钥:签名、加密、鉴权及SSH验证(0个评论)
    • GnuPG(GPG)密钥创建的流程步骤(0个评论)
    • Laravel 9.24版本发布(0个评论)
    • windows系统phpstudy环境中安装amqp拓展流程步骤(0个评论)
    • windows10+docker desktop使用docker compose编排多容器构建dnmp环境(0个评论)
    • windows10+docker desktop运行laravel项目报错:could not find driver...(0个评论)
    • windows10+docker desktop报错:docker: Error response from daemon: user declined directory sharing(0个评论)
    • go语言中Pat多路复用器路由功能示例代码(0个评论)
    • go语言中HttpRouter多路复用器路由功能示例代码(0个评论)
    • js中使用Push.js通知库将通知推送到浏览器(0个评论)
    • 近期评论
    • nkt 在

      阿里云香港服务器搭建自用vpn:Shadowsocks使用流程步骤中评论 用了三分钟就被禁了,直接阿里云服务器22端口都禁了..
    • 熊丽 在

      安装docker + locust + boomer压测环境实现对接口的压测中评论 试试水..
    • 博主 在

      阿里云香港服务器搭建自用vpn:Shadowsocks使用流程步骤中评论 @test  也可能是国内大环境所至,也是好事,督促你该研究学习新技术..
    • test 在

      阿里云香港服务器搭建自用vpn:Shadowsocks使用流程步骤中评论 打了一次网页,然后再也打不开了。。是阿里云的缘故吗?..
    • 博主 在

      centos7中Meili Search搜索引擎安装流程步骤中评论 @鹿   执行以下命令看看你的2.27版本是否存在strin..
    • 2016-10
    • 2016-11
    • 2017-07
    • 2017-08
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2020-10
    • 2020-11
    • 2021-01
    • 2021-02
    • 2021-03
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-04
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客