Плохо, где есть производительность в Laravel

Я хочу применить where условие отношения. Вот что я делаю:

Replay::whereHas('players', function ($query) {
$query->where('battletag_name', 'test');
})->limit(100);

Он генерирует следующий запрос:

select * from `replays`
where exists (
select * from `players`
where `replays`.`id` = `players`.`replay_id`
and `battletag_name` = 'test')
order by `id` asc
limit 100;

Который выполняется за 70 секунд. Если я вручную переписать запрос, как это:

select * from `replays`
where id in (
select replay_id from `players`
where `battletag_name` = 'test')
order by `id` asc
limit 100;

Выполняется за 0,4 секунды. Зачем where exists такое поведение по умолчанию, если оно такое медленное? Есть ли способ сгенерировать правильный where in запрос с помощью построителя запросов или мне нужно ввести сырой SQL? Может я вообще что-то не так делаю?

replays таблица имеет 4M строк, players имеет 40M строк, все соответствующие столбцы проиндексированы, набор данных не помещается в память сервера MySQL.

Обновить: обнаружил, что правильный запрос может быть сгенерирован как:

Replay::whereIn('id', function ($query) {
$query->select('replay_id')->from('players')->where('battletag_name', 'test');
})->limit(100);

Еще есть вопрос почему exists работает так плохо и почему это поведение по умолчанию

7

Решение

Я думаю, что производительность не зависит от того, где есть, только зависит от того, сколько записей вы выбрали

Плюс попробуйте оптимизировать ваш сервер MySQL

https://dev.mysql.com/doc/refman/5.7/en/optimize-overview.html

а также оптимизировать ваш php сервер

и если у вас есть быстрый запрос, почему бы вам не использовать необработанный объект запроса от личинок

$replay = DB::select('select * from replays where id in (
select replay_id from players where battletag_name = ?)
order by id asc limit 100', ['test']
);
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]