我有一张约有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 查询只会挂起系统。
答案 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的查询规划器对于从属子查询有点天真,有时会重复它们直到太阳变成白矮星。