Мой запрос на выбор очень медленный, мне нужно понять, как его улучшить - PullRequest
0 голосов
/ 24 апреля 2020

У меня есть запрос, который я использую для получения данных таблицы. Запрос выполняется очень медленно, когда возвращается более 3-4 строк, и я не понимаю, почему.

Это мой запрос:

select 
        ig.id,
        ig.username,
        ig.created,
        ig.is_completed,
        ig.user_id,
        ig.is_error,
        ig.last_appeal_process_update,
        (unix_timestamp() - ig.created) as time_running,
        ig.is_deleted,
        ap.id as appealprocessid,
        (case 
            when ap.id is null then 0
            when ap.id is not null then ap.status
        end
        ) as current_status,
        ( select count(*) from appeal_process where ig_account_id = ig.id)
        as total_appeals
        from instagram_accounts ig
        left join appeal_process ap on ig.id = ap.ig_account_id
        where 
        (ig.username like CONCAT('%',?,'%') or ig.id like CONCAT('%',?,'%') or ig.username like CONCAT('%',?,'%')) and 
        ig.user_id = ? and is_deleted = 0 and 
        (
            ap.id is null or
            ap.id = ( -- WE SELECT ONLY THE LATEST APPEAL PROCESS
                select max(id) from appeal_process tmp where tmp.ig_account_id = ig.id limit 1
            )   
        )
        order by ig.username asc
        limit ?,?

РЕДАКТИРОВАТЬ

Это запрос EXPLAIN (хотя я не знаю, как его прочитать) введите описание изображения здесь

Это SHOW CREATE TABLE для instagram_accounts: введите описание изображения здесь

Это SHOW CREATE TABLE для appeal_process: введите описание изображения здесь

Ответы [ 2 ]

0 голосов
/ 24 апреля 2020

На instagram_accounts у вас есть заданные критерии c до user_id, is_deleted, но также username. Поскольку вы также сортируете по имени пользователя, первое исправление заключается в добавлении индекса.

CREATE INDEX user_id_deleted_username ON
             instagram_accounts(user_id, is_deleted, username);

В appeal_process вы ищете по ig_account_id как в подзапросе JOIN, так и tmp:

CREATE INDEX id_account_id ON 
             appeal_process ( ig_account_id)

В запросе вы получаете статус максимального идентификатора процесса апелляции для пользователя. Позволяет GROUP BY ig.id, и это упрощает получение результатов, поскольку MAX и другие для каждой группы (изменения в CAP для акцентирования):

select 
        ig.id,
        ig.username,
        ig.created,
        ig.is_completed,
        ig.user_id,
        ig.is_error,
        ig.last_appeal_process_update,
        (unix_timestamp() - ig.created) as time_running,
        ig.is_deleted,
        COALESE(MAX(ap.id),0) as appealprocessid,
        (SELECT status FROM appeal_process WHERE appeal_process.id = appealprocessid LIMIT 1) as current_status,
        COUNT(*) as total_appeals
        from instagram_accounts ig
        left join appeal_process ap on ig.id = ap.ig_account_id
        where 
        (ig.username like CONCAT('%',?,'%') or ig.id like CONCAT('%',?,'%') or ig.username like CONCAT('%',?,'%')) and 
        ig.user_id = ? and is_deleted = 0 
        GROUP BY ig.id
        order by ig.username asc
        limit ?,?
0 голосов
/ 24 апреля 2020

Весьма вероятно, что ваша проблема связана с отсутствием индексов, необходимо проиндексировать поля, используемые в предложениях WHERE AND JOIN.

Создать индекс для каждого из этих полей:

ig_account_id

ig.id

ig.username

is_deleted

ig.user_id

tmp.ig_account_id

...