Получение последнего элемента в groupBy - PullRequest
0 голосов
/ 17 мая 2018

Я нашел несколько ответов, за которыми следовал, обнаружил, что это работает локально, поэтому я поднялся до нашего тестового бокса, где я обнаружил, что запросы к этой конкретной БД длится более 1300 секунд, зайдя в mysql и * 1001. * и он висит на 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();

1 Ответ

0 голосов
/ 17 мая 2018

Вы можете попробовать запустить следующее:

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`;

Объединения обычно выполняются быстрее, чем наоборот, но я не думаю, что это поможет, потому что вы, очевидно, не группируете по индексам. Для этого вам придется изменить структуру, и я настоятельно рекомендую это сделать. Попробуйте уменьшить максимальную длину имени, фамилии и имени, чтобы вы могли создать комбинированный индекс из этих трех. Если вы можете изменить саму структуру базы данных, не убивая половину своей системы, вам следует подумать о нормализации этой таблицы, например, иметь таблицу с посетителями, а другую - с посещениями этих посетителей (связь с внешними ключами), чтобы вместо этого можно было группировать по ключу. группировки по трем неиндексированным строкам большой длины.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...