MySQL NOT IN查询需要太长时间才能响应

时间:2017-02-22 14:53:50

标签: mysql notin

查询需要很长时间才能响应~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版本的上述查询。

consumer表有

  • consumer_id varchar(12)
  • active_flag varchar(6)
  • frequency varchar(2)
  • 130000使用where子句
  • 的行
  • 总行数160000
  • consumer_id上的唯一索引
  • 有关active_flag的索引

transaction表有

  • consumer_id varchar(12)
  • active_flag varchar(6)
  • status varchar(20)
  • cycle varchar(13)
  • 108000行where where子句
  • 总行数270000
  • 关于consumer_id状态和周期的索引

服务器配置

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

解释回报 SQL QUERY EXPLAIN

我希望这会有所帮助。 提前谢谢。

更新1

消费者和交易具有一对多的关系 所以consumer_id将在每个周期重复。<​​/ p>

4 个答案:

答案 0 :(得分:0)

使用左连接,您将获得'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' )

答案 1 :(得分:0)

使用右连接或内连接来获得所需的结果。 为了加快查询速度,您应该为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'

答案 2 :(得分:0)

我不确定您的数据是什么样的,所以我不确定以下内容是否有效,但您可能希望使用查询的基础逻辑,因为您希望在不使用子查询的情况下实现目标。

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

答案 3 :(得分:0)

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。