2017-02-22 304 views
1

查询需要很长时间才能响应〜40分钟。MySQL NOT IN查询花费太长的时间来响应

`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)
  • 频率VARCHAR(2)
  • 130000行与where子句
  • 行总数160000
  • consumer_id上的唯一索引
  • in DEX上active_flag

transaction表具有

  • consumer_id VARCHAR(12)
  • active_flag VARCHAR(6)
  • 状态VARCHAR(20)
  • 周期VARCHAR(13)
  • 108000行,其中有条款
  • 总排数270000
  • 指数consumer_id状态和循环

服务器配置

-16GB RAM -8核Intel(R)至强(R)CPU E5-4640 V2 @ 2.20GHz -MySQL 35年5月6日

解释回报 SQL QUERY EXPLAIN

我希望这有助于。 在此先感谢。

更新1

消费和交易有一个一对多的关系 所以consumer_id会重复每一个周期。

+0

请问您还可以添加您的JOIN查询吗? – marijnz0r

回答

0

内加入的伎俩,我

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。

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') 
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' 
0

我不知道你的数据是什么样子,所以我不能确定,如果下面的工作,但你可能要与您的查询的基本逻辑玩,因为你正在寻找这样做应该是没有达到什么使用子查询。

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