Производительность whereHas laravel

#laravel

#laravel

Вопрос:

Я прочитал много статей, предупреждающих о производительности whereHas (он использует подзапрос в where exists), когда данные большие (здесь: 18415, 5328, …). В моем случае ниже мне нужно будет его заменить? И как?.
Таблица продуктов

  ---- --------------------- 
| id |     created_at      |
 ---- --------------------- 
|  1 | 2020-10-10 10:10:10 |
|  2 | 2020-10-10 10:10:10 |
 ---- --------------------- 
  

Таблица product_translations(индексы: map_id, language_code, slug)

  ---- -------- --------------- ----------- ----------- 
| id | map_id | language_code |   name    |   slug    |
 ---- -------- --------------- ----------- ----------- 
|  1 |      1 | en            | name en 1 | name-en-1 |
|  2 |      1 | es            | name es 1 | name-es-1 |
|  3 |      2 | en            | name en 2 | name-en-2 |
|  4 |      2 | es            | name es 2 | name-es-2 |
 ---- -------- --------------- ----------- ----------- 
  

Product.php

 function translation(){
    return $this->hasOne('AppModelsProductTranslation', 'map_id', 'id');
}
  

ProductController.php

 function view($slug){
    $currentItem = Product::with(['translation' => function($q) use($slug){
            $q->where(['slug' => $slug, 'language_code' => App::getLocale()]);
        }])->whereHas('translation', function($q) use ($slug){
            $q->where(['slug' => $slug, 'language_code' => App::getLocale()]);
        })
    if ($currentItem == null) {
        abort(404);
    }
    return view('product.view', compact('currentItem'));
}
  

Я использую laravel 8x.

Ответ №1:

Вы можете заменить whereHas на whereIn .

 $currentItem = Product::with(['translation' => function($q) use($slug){
    $q->where(['slug' => $slug, 'language_code' => App::getLocale()]);
}])->whereIn(
    'id',
    ProductTranslation::select('map_id')
        ->where(['slug' => $slug, 'language_code' => App::getLocale()])
);
  

Выберите внешний ключ из подвыборки и использует его с where in .