У меня есть 4 таблицы: места, бренды, категории, местоположения.
Отношения являются местами, принадлежащими брендам и местам ManytoMany с категориями и местоположениями.
Я хочу получить результаты поиска Места сопределенная категория и местоположение, но показывает только 1 место для бренда.
Информация о таблицах places
таблица содержит около 100k + строк
place_category
сводная таблица содержит 650k + строк с place_category.place_id
и places.brand_id
столбец индексируется
place_locations
сводная таблица содержит около 550k + строк, с индексами place_location.place_id
и place_location.location_id
индексируется
Запрос, который я получил до сих пор
Place::join('place_location', function ($join) use($city){
$join->on('place_location.place_id', '=', 'places.id')
->where('place_location.location_id', '=', $city->id);
})
->join('place_category', function ($join){
$join->on('place_category.place_id', '=', 'places.id')
->where('place_category.category_id', '=', $category->id);
})->groupBy('places.brand_id')->take(5)->get();
groupBy
, вызывающее медленное время запроса, составляет около 2 секунд.
Результат объяснения выглядит следующим образом
id | select_type | table | possible_key | key |key_len| ref |rows | Extra
1 | SIMPLE | place_location | place_id,location_id | location_id| 4 | const |34790 |Using temporary; Using filesort
1 | SIMPLE | places | PRIMARY | PRIMARY | 4 | db.place_location.place_id | 1 | Using where
1 | SIMPLE | place_category | place_id | place_id | 4 | db.place_location.place_id | 2 | Using index condition; Using where
Запрос Raw Mysql выглядит следующим образом
select `products`.`id`, `products`.`name`, `products`.`display`, `products`.`status_a`, `products`.`status_b`, `products`.`brand_id`, `products`.`address` from `products` inner join `product_location` on `product_location`.`product_id` = `products`.`id` and `product_location`.`location_id` = 4047 inner join `product_category` on `product_category`.`product_id` = `products`.`id` and `product_category`.`category_id` = 102 where `products`.`status_a` != 1 and `status_b` = 2 and `display` >= 5 group by `products`.`brand_id` limit 4
Есть идеи, как улучшить запрос? неправильные показатели? или плохой запрос?