Laravelで小テーブルの件数を取得するなら「withCount」を使おう
Laravel, Eloquentで小テーブルの件数を取得するなら「withCount」を利用しよう
[ 目次 ]
はじめに
こんにちは、香港に住んでいるWEBデベロッパーのなかむ(@nakanakamu0828)です。
今回はLaravel開発中に気になったことをメモとして残しておきたいと思います。
皆さん N+1問題 の解決方法として with を利用していると思いますが、小テーブルの件数を取得したい場合は「withCount」 を利用しよう!っというお話です。
■ 検証環境
PHP | Laravel |
---|---|
^7.2.4 | 5.7.* |
例としてのデータ構造
ER図
Model
■ Userモデル
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function posts()
{
return $this->hasMany('App\Models\Post');
}
}
■ Postモデル
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function user()
{
return $this->belongsTo('App\Models\User');
}
}
ダメなコーディング
$users = User::all();
foreach($users as $user) {
$posts_count = $user->posts()->count();
}
SELECT * FROM users;
SELECT COUNT(*) FROM posts WHERE user_id = 1;
SELECT COUNT(*) FROM posts WHERE user_id = 2;
SELECT COUNT(*) FROM posts WHERE user_id = 3;
・・・
ユーザーの数だけ投稿の検索が実行されます。
良いコーディング
$users = User::withCount('posts')->all();
foreach($users as $user) {
$posts_count = $user->posts_count;
}
SELECT users.*, (select count(*) from posts where users.id = posts.user_id) as 'posts_count' from users;
1つしかクエリーが実行されません。