MySQL NOT IN 查询响应时间过长

MySQL NOT IN query taking too long to respond

查询响应时间太长,大约需要 40 分钟。

`SELECT c.consumer_id FROM consumer c
WHERE  c.active_flag = 'Y'
      AND ( c.frequency = 'Q' )
      AND c.consumer_id NOT IN(
  SELECT consumer_id
  FROM (SELECT s.consumer_id
        FROM transactions s
        WHERE ( s.cycle='2016-Q-2' ) and s.active_flag = 'Y' AND s.status <> 'Door Locked')
    AS subquery)`

我也尝试过同时使用上述查询的 NOT EXISTS 和 LEFT JOIN / IS NULL 版本。

consumertable有

transactiontable有

服务器配置

-16GB 内存 -8 核心 Intel(R) Xeon(R) CPU E5-4640 v2 @ 2.20GHz -MySQL 5.6.35

解释一下return SQL QUERY EXPLAIN

希望对您有所帮助。 提前致谢。

更新 1

消费者和交易是一对多的关系 所以 consumer_id 将在每个周期重复。

使用左连接你会得到 'NULL' 个值

尝试使用内部联接可能对您有帮助

SELECT c.consumer_id FROM consumer c
JOIN 
    (SELECT s.consumer_id as S_ID 
     FROM transactions s
     WHERE (s.cycle='2016-Q-2') and s.active_flag = 'Y' AND s.status <> 
    'Door Locked')
ON s.S_ID <> c.consumer_id
WHERE  c.active_flag = 'Y' AND ( c.frequency = 'Q' )

使用右连接或内连接以获得您想要的结果。 为了加快查询速度,您应该为 WHERE 子句中的所有字段添加索引。祝你好运!

SELECT DISTINCT c.consumer_id FROM consumer c
INNER JOIN transactions s
ON s.cycle != '2016-Q-2' AND s.active_flag != 'Y' AND s.status = 'Door Locked' 
WHERE  c.active_flag = 'Y'
AND c.frequency = 'Q'

我不确定您的数据是什么样的,所以我不确定以下是否有效,但您可能想尝试一下查询的基本逻辑,因为您想要做的事情应该可以在不使用的情况下实现子查询。

作为一般规则,您总是希望远离使用子查询,因为它们效率极低。

Inner Join 帮了我大忙

SELECT DISTINCT c.consumer_id FROM consumer c
INNER JOIN
    (SELECT DISTINCT consumer_id as sid from transactions where consumer_id not in (
  select consumer_id from transactions
  where cycle = '2016-Q-2' AND active_flag = 'Y' AND status != 'Door Locked'
)) as s
ON s.sid = c.consumer_id
WHERE  c.active_flag = 'Y' AND ( c.frequency = 'Q' )

不确定这是否正确,但响应时间现在已降至 ~ 700 毫秒。

不知道为什么,但上述所有答案的查询响应都提供了交易中可用的所有消费者 ID table。