Я нашел здесь несколько ответов, за которыми я следил, обнаружил, что он работает локально, поэтому я поднялся до нашего тестового окна, где я обнаружил, что этот конкретный запрос к БД длится более 1300 секунд, войдя в mysql и SHOW PROCESSLIST;, и он висит. copying to tmp table
Это Laravel 4.2, довольно старый устаревший код, который я просто пытаюсь стабилизировать, работая над более поздней версией. Этот код ниже повторяется примерно каждые 30 секунд в соответствии с api_call, что все хорошо, за исключением того, что он не завершает и не получает 504 Gateway Time-out. Я чувствую, что делаю что-то рекурсивное, или очистка действительно большой базы данных будет проблемой здесь?
Все, что я пытаюсь сделать, это запустить groupBy, но вместо группировки по первому, я хочу сгруппировать по последнему, на случай обновления других деталей.
Любая предоставленная помощь будет принята с благодарностью.
public function api_prevnames()
{
if (Auth::user()->repeat_vistor == 'Y') {
$names = DB::table('visitors')
->select(DB::raw('first_name,last_name,email,car_reg,OPTIN,vistor_company'))
->where('user_id', Auth::user()->id)
->where('hidden', 0)
->where('email', '<>', '')
->whereRaw('id IN (select MAX(id) FROM visitors GROUP BY first_name, last_name, email)')
->get();
}
return JSONResponseGenerator::successResponse($names->toArray());
}
Что генерирует этот запрос
select first_name,last_name,email,car_reg,OPTIN,vistor_company from `visitors` where `user_id` = '439' and `hidden` = '0' and `email` <> '' and id IN (select MAX(id) FROM visitors GROUP BY first_name, last_name, email)
Предыдущий код выполняется чуть менее чем за пару секунд, которые я добавил ниже:
$names = DB::table('visitors')
->select(DB::raw('first_name,last_name,email,car_reg,OPTIN,vistor_company'))
->where('user_id', Auth::user()->id)
->where('hidden', 0)
->where('email', '<>', '')
->groupBy('first_name', 'last_name', 'email')
->get();






Вы можете попробовать запустить следующее:
SELECT
first_name,
last_name,
email,
car_reg,
OPTIN,
vistor_company
FROM (
SELECT
MAX(id) AS id
FROM `visitors`
WHERE
`user_id` = 439
AND `hidden` = 0
AND `email` <> ''
GROUP BY
first_name,
last_name,
email
) AS subQ
NATURAL JOIN `visitors`;
Соединения обычно быстрее, чем наоборот, но я не думаю, что это поможет, потому что вы, очевидно, не группируете по индексам. Для этого вам придется изменить структуру, и я настоятельно рекомендую это сделать. Постарайтесь уменьшить максимальную длину first_name, last_name и email, чтобы вы могли создать объединенный индекс из этих трех. Если вы можете изменить саму структуру базы данных, не убивая половину вашей системы, вам следует подумать о нормализации этой таблицы, например, иметь таблицу с посетителями, а другую - с посещениями этих посетителей (связь с внешними ключами), чтобы вместо этого вы могли группировать по ключу группировки по трем неиндексированным строкам большой длины.
Абсолютно разбитый приятель, делает именно то, что мне нужно, и довольно быстро!
Я обновил вашу правку, чтобы добавить точный процесс, который я сделал, чтобы исправить это в Laravel. Очень признателен за вашу помощь.