ORMは便利ですが、何度も重複するクエリを発行しがちです。複数のモデルオブジェクトeachしてリレーション先を参照する時は特に危険です。どれくらい重複してるかは
barryvdh/laravel-debugbar: Laravel Debugbar (Integrates PHP Debug Bar)
などで調べるのが楽です。duplicatedとuniqueに分けてくれます。
やり方の方針はクエリが発行される度にそのクエリに対応するキャッシュはあるかチェック、あるならばキャッシュを結果として取得、なければ実際に発行して結果を取得してキャッシュに保存、です。
一つのクエリに使う場合は次です。
$key = __FILE__.' '.__FUNCTION__.' '.__LINE__ .' '.$id; app()->offsetExists($key) ?: app()->singleton($key, static function () use ($id){ return Member::where('id',$id)->get(); });
コードの場所と引数に関して一意になるキーを設定。クエリの結果をシングルトンに登録することによって、同じ場所が同じ引数で繰り返し呼ばれる際、同じクエリを発行することなく、Laravel内にバインドされたシングルトンを呼ぶようになります。変数なのでプロセスが終わったら揮発します。
作った後しばらくして気づきましたがarrayドライバ(array型の変数内にキャッシュを保存する機能)でキャッシュ使った方がシンプルですね。
全体のクエリに使う場合はDBのselect等データ取得時のリスナーに同じ処理を入れます。updateした時のリスナーにキャッシュ消す処理忘れるとバグの元になります。