3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Laravel] N+1問題について少し調べた

Last updated at Posted at 2021-04-07

概要

面接の際にN+1問題について問われたのですが、あまりうまく答えられなかったので整理します。
主にLaravelでのN+1問題について記述します。

間違っている部分等ありましたらご指摘いただけると幸いです。

N+1問題

LaravelはEloquent ORMを使用されます。

ORMとはデータベースのレコードをオブジェクトとして直感的に扱えるようにするものです。
生のSQLで書く必要がないため、RDBへアクセスする処理を簡単に行うことができます。

そして、Eloquentのリレーションはデフォルトとして「遅延ロード」されますが、それを「Eagerロード」にすることでN+1問題を解決することができます。

「遅延ロード」と「Eagerロード」

では、遅延ロードとEagerロードとの違いについて見ていきます。

以下の関係のテーブルがあった場合(公式より抜粋)

Book.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Book extends Model
{
    /**
     * この本を書いた著者を取得
     */
    public function author()
    {
        return $this->belongsTo('App\Author');
    }
}

遅延ロードで全書籍と著者を取得すると以下のようになります。

.php
$books = App\Book::all();

foreach ($books as $book) {
    echo $book->author->name;
}

この場合、

.php
echo $book->author->name;

が実行されることで初めてBookとAuthor間のリレーションデータが取得されます。

つまり、echo $book->author->name;が行われるたびに

Book.php
    public function author()
    {
        return $this->belongsTo('App\Author');
    }

にアクセスをしてデータを取得していることとなります。

ですので、上記の例だとBookの数だけselect文が発行されることになってしまいます。

このことをN+1問題と言うみたいです。

そしてN+1問題を解決するためにEagerロードと言うものが存在します。

遅延ロードだと
1.Authorのリレーションデータを持っていないBookモデルコレクションを取得
2.リレーションデータにアクセスするたびにリレーションデータを取得
以下手順2をループ

に対して
1.Authorリレーションデータを事前に取得したBookモデルコレクションを取得

とすることでクエリの発行を最小限に抑えることができます。

LaravelでのEagerロードはwithを使うことで行うことができます。

.php

// 遅延ロード
$books = App\Book::all();
// Eagerロード
$books = App\Book::with('author')->get();

また、N+1問題の検知は以下のようなパッケージがあるみたいです。(まだ触っていないのでなんとも言えないですが)
https://github.com/beyondcode/laravel-query-detector

まとめ

わかっているつもりでプログラムを書いていましたが、改めて調べてみることで全然理解できていないなと痛感しました。

参考文献

公式
オブジェクト関係マッピング
Laravelでリレーションのあるテーブルをwithで取得する【N+1問題】
LaravelでN+1を検出させる

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?