LoginSignup
2
4

More than 1 year has passed since last update.

Laravel Eloquent の whereHas が遅い

Last updated at Posted at 2020-10-12

バージョン

Laravel5.4

whereHas を用いた場合

whereHasメソッドを用いると処理が重くなります。

$query->when($filter->get('category_id'), function ($query) use ($filter) {
    $query->whereHas('categories', function ($query) use ($filter) {
        $query->whereIn('category_id', $filter->get('category_id'));
    });
});       

解決方法

Github の issue に解決策が記載されていました。
whereHasメソッドの代わりに、whereInメソッドを用いる。

Laravel is creating a temporary column on literally every row in the database, in which it fills with true or false. If any indexes can be used, they are probably used after this. Any query that uses whereHas is probably going to be a full table scan.

Here is a similar query, except it does not induce full table scans.

Profile::whereIn('profiles.id', function($query) use ($mac_address) {
    $query->from('devices')
        ->select('devices.profile_id')
        ->where('devices.mac_address', $mac_address);
})

処理が重かった whereHasを用いたソースを whereIn を用いた形に修正すると下記のようになります。

$query->when($filter->get('category_id'), function ($query) use ($filter) {
    $query->whereIn('id', function ($query) use ($filter) {
        $query->from('content_category')
            ->select('content_id')
            ->where('category_id', $filter->get('category_id'));
    });
});        

参考

WhereHas query is too slow #18415

2
4
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
2
4