MYSQLI запрос, ГДЕ НЕ ВХОДИТЕ (ВЫБРАТЬ) - PullRequest
0 голосов
/ 29 ноября 2018
>     SELECT 
>         SUM(m_out) AS totalOut
>     FROM
>         m_detal
>     WHERE
>         opers = '25'
>             AND (m_type = 'Out'
>             OR m_type = 'Merged')
>             AND m_date <= '2018-11-28 07:30:00'
>             AND mark_delete IS NULL
>             AND m_ids NOT IN (SELECT 
>                 m.m_ids
>             FROM
>                 (SELECT 
>                     m_ids
>                 FROM
>                     m_detal
>                 WHERE
>                     opers = '25'
>                         AND (m_type = 'Out'
>                         OR m_type = 'Merged')
>                         AND (m_onhold != 'onhold'
>                         OR m_onhold IS NULL)
>                         AND mark_delete IS NULL
>                         AND m_date <= '2018-11-28 07:30:00') AS m
>                     INNER JOIN
>                 n_combine_tbl AS t ON (t.comb_id1 = m.m_ids
>                     OR t.comb_id2 = m.m_ids)
>                     AND t.time <= '2018-11-28 07:30:00');

Этот запрос занял у меня больше 30 секунд или больше!Запрос внутри NOT IN немного огромен, около 7-9 тыс. Идентификаторов.Есть ли более эффективный способ сделать это?Я думаю, что внутренняя часть соединения состоит в том, чтобы замедлить проверку двух столбцов n_combine_tables (comb_id1 или comb_id2).

Есть ли более эффективный способ сделать это?

1 Ответ

0 голосов
/ 29 ноября 2018

Я бы удалил дублированные условия в подзапросах и сделал бы что-то вроде этого (два NOT in можно заменить на UNION):

SELECT
    SUM(m.m_out) AS totalOut
FROM
    m_detal AS m
WHERE
        m.opers = '25'
    AND m.m_type IN ('Out', 'Merged')
    AND m.m_date <= '2018-11-28 07:30:00'
    AND m.mark_delete IS NULL
    AND m.m_onhold = 'onhold'
    AND m.m_ids NOT IN (
        SELECT 
            t1.comb_id1
        FROM
            n_combine_tbl AS t1
        WHERE
            t1.time <= '2018-11-28 07:30:00'
    )
    AND m.m_ids NOT IN (
        SELECT 
            t2.comb_id2
        FROM
            n_combine_tbl AS t2
        WHERE
            t2.time <= '2018-11-28 07:30:00'
    )
;

ИЛИ с NOT EXISTS:

SELECT
    SUM(m.m_out) AS totalOut
FROM
    m_detal AS m
WHERE
        m.opers = '25'
    AND m.m_type IN ('Out', 'Merged')
    AND m.m_date <= '2018-11-28 07:30:00'
    AND m.mark_delete IS NULL
    AND m.m_onhold = 'onhold'
    AND NOT EXISTS (
        SELECT 
            *
        FROM
            n_combine_tbl AS t
        WHERE
                t.time <= '2018-11-28 07:30:00'
            AND (
                   t.comb_id1 = m.m_ids
                OR t.comb_id2 = m.m_ids
            )
    )
;
  1. Вы должны проверить логику 'onhold'.
  2. Вы должны попытаться добавить индексы для n_combine_tbl: (время, comb_id1), (время, comb_id2), (comb_id1, время), (comb_id2,время) и проверьте, что хорошо для ваших данных.
  3. Следует также учитывать индексы с несколькими столбцами в таблице m_detal.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...