【问题标题】:How to optimize "WHERE NOT IN" with subquery如何使用子查询优化“WHERE NOT IN”
【发布时间】:2014-01-14 10:19:09
【问题描述】:

我有这个问题,这个线程中的讨论输出是什么: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 条记录。 127 个结果行的查询耗时 > 30 秒。

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

【问题讨论】:

  • 如果您解决了问题,请添加解决方案(使用的索引)作为答案。

标签: mysql optimization subquery notin


【解决方案1】:

您的查询有一些 group by 问题(实际上,您不应该有任何 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

我还用别名稍微整理了查询。

【讨论】:

  • @AngularAddict 嗯?我有2行。你确定你刷新了页面?这是小提琴链接:sqlfiddle.com/#!2/e97cf/34
  • 问我缓存了页面。作品。谢谢你。
【解决方案2】:

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

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

查询现在大约需要 200 毫秒

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多