Проблема заключается в том, как Laravel заставляет withCount()
работать - он генерирует что-то вроде этого:
SELECT `comments`.*,
(SELECT Count(*)
FROM `images`
WHERE `comment_id`.`id` = `comments`.`id`
AND `images`.`shop_name` = 'your shop') AS `images_count`
FROM `comments`
WHERE `shop_name` = 'your_shop'
ORDER BY `images_count`
Это заставит MySQL выполнять count()
подзапрос для каждого комментария указанного магазина.
Здесь нужно сделать этот коррелированный подзапрос (который выполняется для каждой строки) в независимый запрос (который выполняется только один раз), а затем использовать соединения, чтобы MySQL соединяет все это:
$imagesCountQuery = DB::table('comments')
->selectRaw('comments.id AS comment_id, COUNT(comments.id) AS images_count')
->join('images', 'images.comment_id', '=', 'comments.id') /* !!! */
->where('images.shop_name', '=', $shop)
->groupBy('comments.id');
$data = Comment::joinSub($imagesCountQuery, 'images_count_sub', function ($join) {
$join->on('comments.id', '=', 'images_count_sub'.'comment_id'); /* !!! */
})->where('shop_name', $shop)->orderBy('images_count_sub.images_count', 'desc')->paginate(10);
!!! - эти строки должны быть изменены, чтобы представить отношение images
вашего комментария. В этом примере я просто предположил, что это было отношение hasMany
, поскольку вы не указали это в своем вопросе.