如何使用子查询优化“WHERE NOT IN”

时间:2014-01-14 10:19:09

标签: mysql optimization subquery notin

我有这个查询在这个帖子中讨论输出的内容:Mysql JOIN subquery

查看当前小提琴:http://sqlfiddle.com/#!2/e97cf/22

create table c_contact 
(id INT, 
 name VARCHAR(20), 
 securityid INT
);

create table c_monitoring 
(started DATE, 
 ended DATE DEFAULT NULL, 
 securityid INT
);


SELECT
  c_contact.id,
  c_contact.name,
  c_contact.securityid
FROM c_contact
WHERE c_contact.securityid != ''
  AND c_contact.securityid NOT IN
      (select securityid 
       from c_monitoring 
       where ended is null 
       group by securityid
      )
GROUP BY c_contact.id ;

我该如何优化这个查询呢?我在c_contact表中有100.000条记录,在c_monitoring表中有大约10.000条记录。查询需要> 30秒,结果行数为127。

编辑:通过正确索引表来解决案例。

2 个答案:

答案 0 :(得分:2)

您的查询有一些问题(实际上,您不应该有任何group by子句),您应该将其转换为连接:

SELECT
  c.id,
  c.name,
  c.securityid
FROM c_contact c
LEFT JOIN c_monitoring m ON m.securityid = c.securityid
  AND m.ended is null
WHERE c.securityid != ''
AND m.securityid IS NULL

请参阅SQLFiddle

我还用别名整理了一些查询。

答案 1 :(得分:0)

案例通过索引表字段来解决

  • c_contact.securityid
  • c_monitoring.started
  • c_monitoring.ended
  • c_monitoring.securityid

查询现在需要~200ms