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
)
)
;
- 您应该检查“暂停”逻辑。
- 您应该尝试在 n_combine_tbl 上添加索引:(time,comb_id1)、(time,comb_id2)、(comb_id1,time)、(comb_id2,time),并检查哪些索引对您的数据有利。
- 还应考虑 m_detal 表上的多列索引。
关于mysql - 查询 WHERE NOT IN (SELECT) INNER JOIN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53531092/