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

时间:2016-11-17 12:41:05

标签: mysql query-performance

我有一张约有20000条记录的表格。我正在运行此查询

SELECT DISTINCT t.ci_record_id FROM `ip_connection` t WHERE
  t.remote_ip NOT IN (
    SELECT DISTINCT t1.ipAddress FROM ci_table t1 WHERE 
          t1.blueprint_id IN (SELECT t2.id FROM blueprints t2 WHERE t2.ci_part=FALSE) 
      AND t1.archive=FALSE
  );

相同的查询如果我使用 IN 子句运行,它将在几秒钟内运行并返回18000条记录。 NOT IN 查询只会挂起系统。

1 个答案:

答案 0 :(得分:1)

您可以使用LEFT JOIN ... IS NULL模式来提升此功能。这是一个值得尝试的东西。

SELECT DISTINCT t.ci_record_id 
  FROM ip_connection t
  LEFT JOIN (
         SELECT DISTINCT t1.ipAddress 
           FROM ci_table t1 
           JOIN blueprints t2    ON t1.blueprint_id = t2.i2
                                AND t2.ci_part=FALSE
          WHERE t1.archive = FALSE
        ) ta ON t.remote_ip = ta.ipAddress
  WHERE ta.ipAddress IS NULL

我在这里所做的是将你的从属子查询(你的NOT IN)子句中的子查询考虑在内,并将其作为一个独立的子查询,就像这样。

         SELECT DISTINCT t1.ipAddress 
           FROM ci_table t1 
           JOIN blueprints t2    ON t1.blueprint_id = t2.i2
                                AND t2.ci_part=FALSE
          WHERE t1.archive = FALSE

您应该能够独立测试此子查询。它应该产生与未归档蓝图项列表对应的未归档t1项列表。

然后,我LEFT JOIN将它编辑到你的顶层表,然后我在连接的右侧查找了NULL项。那些NULL项对应于连接左侧与ON子句不匹配的行。这是独立的子查询方式NOT IN

这可能会对你有所帮助,因为MySQL的查询规划器对于从属子查询有点天真,有时会重复它们直到太阳变成白矮星。