MYSQLI查询WHERE NOT IN(SELECT)INNER JOIN

时间:2018-11-29 02:44:56

标签: mysql mysqli

>     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内的查询在ID的7-9k左右有点大。有更有效的方法吗?我认为在检查n_combine_tables的两列(comb_id1或comb_id2)时,内部连接部分会使它变慢。

是否有更有效的方法?

1 个答案:

答案 0 :(得分:0)

我将删除子查询中的重复条件,并执行类似的操作(两个NOT NOT可以用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'
    )
;

或不存在:

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. 您应该检查“保留”逻辑。
  2. 您应该尝试在n_combine_tbl上添加索引:(时间,comb_id1),(时间,comb_id2),(时间comb_id1,时间),(时间comb_id2,时间),并检查对您的数据有什么好处。
  3. 还应考虑m_detal表上的多列索引。