

Laravelを使用して開発を行っています。

`belongsTo` メソッドを使用してテーブルデータを取得しているのですが、下記のような処理で `$datas`
が1万カウント分のデータを取得する際に4分ほどの時間がかかってしまいます。  
処理速度の向上を行いたく、テーブルにアクセスする際に `belongsTo` メソッドに代わる処理などご存じでしょうか。  
初歩的な質問かと思いますが、よろしくお願い致します。

**現状のコード**

[code]

    public function sample(Request $request)
    {
        $query = $this->getDatasQuery($request);
        $datas = $query->get();
    
        return [
            'datas' => $datas->map(function($data) {
                return [
                    'id' => $data->id,
                    'sub_id' => $data->sub_id,
                    'hoge_id' => $data->data_sub->hoge_id,
                    'hoge_name1' => $data->data_sub->hoge_name1,
                    'hoge_name2' => $data->data_sub->hoge_name2,
                    'hoge_name3' => $data->data_sub->hoge_name3,
                    'result' => $data->data_sub->hoge ? $data->data_sub->hoge->hoge_result : '',
                    'category' => $data->data_sub->hoge ? $data->data_sub->hoge->hoge_category : '',
                    'status' => $data->data_sub->hoge ? $data->data_sub->hoge->hoge_status : '',
                    'info' => $data->data_sub->hoge ? $data->data_sub->hoge->hoge_info : '',
                    'date' => $data->date,
                ];
            }),
        ];
    }
    
    public function data_sub()
    {
        return $this->belongsTo('data_sub');
    }
    
[/code]


CC BY-SA 4.0
2020-05-25T08:05:54.120
66968
2020-05-25T09:24:41.870
2020-05-25T08:09:57.887
3060
29606
question
php laravel
Laravel、PHPにおけるデータ数が多い際の「belongsTo」メソッドに代わる処理方法


提示されたコードだけでは、おそらく各項目の取得においてN+1問題が発生しているように見えます。  
[`with`や`load`によって Eager load](https://readouble.com/laravel/7.x/ja/eloquent-
relationships.html#eager-loading) をすることでクエリ数は大幅に減らせます。

が、1万件のレコードについての処理となると消費するメモリがそこそこになりそうなので分割して行うべきかもしれません。


CC BY-SA 4.0
2020-05-25T09:10:56.417
66971
2020-05-25T09:10:56.417
2376
66968
answer


これbelongTo()に問題があるという前提がそもそも疑問です。まず、1万件をgetしてメモリに格納してから1件ずつ回してますよね。この時点でパフォーマンスかなり悪くなっている印象です。なので、そこをまず改善しましょう。

具体的には、一気にgetするのではなく1000件とかの単位でchunkで読み込むか、cursorで1件ずつ読むか、ですね。パフォーマンスは後者、メモリは前者のほうが節約できるはずです。  
<https://readouble.com/laravel/6.x/ja/queries.html#chunking-results>

そのうえで、data_subはbelongToを使うにせよ、EagerLoadingとなるようにwithで読み込んでください。  
<https://readouble.com/laravel/6.x/ja/eloquent-relationships.html#eager-
loading>

あととても細かい話ですが、dataはdatumの複数形なので、datasという単語は存在しえないですね。


CC BY-SA 4.0
2020-05-25T09:24:41.870
66972
2020-05-25T09:24:41.870
40240
66968
answer