has と whereHas を hasByNonDependentSubquery に置き換えるだけで速度が早くなる。
参考
https://qiita.com/mpyw/items/0761a5e44836c9bebcd5
新しめのphpとlaravelでしか動かないのでバージョンだけ注意。
composer require mpyw/eloquent-has-by-non-dependent-subquery
composer require mpyw/eloquent-has-by-join
両方インストールしておこう。
今回は、現在動いているものと同じ結果が出るのかテストしてみる
略
・・・同じ結果が帰ってくるが、発行されるSQL文が違う
何度か試したが、ほぼ確実に hasByNonDependentSubquery
を利用したほうが早い。
これは、使える。
使い方
has と whereHas を hasByNonDependentSubquery に置き換えるだけ。
あとは全く同じ使い方でOK。
・少なくとも Nailphotos を持っている Nail データを取得
has 13.19
→ hasByNonDependentSubquery 10.64
$sql = Nail::with([
'Iines',
'Nailphotos',
'User.Photos'
]
)->has('Nailphotos');
$res = $sql->paginate(10);
$sql = Nail::with([
'Iine',
'Nailphotos',
'User.Photos'
]
)->hasByNonDependentSubquery('Nailphotos');//置き換える
$res = $sql->paginate(10);
・Nailphotos の id 167 を持つ Nail データを取得 12.11
whereHas 12.11
→ hasByNonDependentSubquery 11.35
$sql = Nail::with([
'Iines',
'Nailphotos',
'User.Photos'
]
)->whereHas('Nailphotos', function ($q) {
$q->where('id',167);
});
$sql = Nail::with([
'Iines',
'Nailphotos',
'User.Photos'
]
)->hasByNonDependentSubquery('Nailphotos', function ($q) {//置き換える
$q->where('id',167);
});
has や whereHas が早くなるのはありがたい。
関連したモデルを持たないもののみ取得する
// $sql->doesntHave('answers');
$sql->doesntHaveByNonDependentSubquery('answers');
マニュアルに載ってなくてテストケース読んだけど
すごいね。かゆいところまで手が届く。