mysql - 查询 WHERE NOT IN (SELECT) INNER JOIN

标签 mysql

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-9k 个 id。有没有更有效的方法来做到这一点?我认为内部联接部分会使检查 n_combine_tables 的两列(comb_id1 或 Comb_id2)的速度变慢。

有没有更有效的方法来做到这一点?

最佳答案

我会删除子查询中的重复条件并执行类似的操作(两个 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 上添加索引:(time,comb_id1)、(time,comb_id2)、(comb_id1,time)、(comb_id2,time),并检查哪些索引对您的数据有利。
  3. 还应考虑 m_detal 表上的多列索引。

关于mysql - 查询 WHERE NOT IN (SELECT) INNER JOIN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53531092/

相关文章:

mysql - 使用 IN 子句进行条件检查 mysql

java - 连接到远程 Amazon RDS mysql 实例的桌面应用程序

葡萄牙语的 MySQL 排序规则

mysql - 从数据库中获取产品

php - Laravel 如何返回并在 HTML 中显示 SQL 错误?

mysql - 在 MySQL 中找出 varchar 是否包含百分号

mysql - SQL 返回一组合并的结果

mysql - 从 MySQL 到 Oracle 的查询

mysql - 编写查询以获取两列相乘的总和

java - 将 19999 年存入数据库