2

我有两张桌子:

表 A:

Name, isPair

表 B:

Name1, Name2, Status

这是我的查询:

SELECT Name
FROM A
LEFT JOIN B ON (A.Name = B.Name2)
WHERE A.isPair = 'T' AND (B.status <> 'valid' OR B.status IS NULL)

我在两个表中都有数百万行。以目前的查询速度,完成需要 3 个多月的时间。我已经适当地索引了这两个表。当我最初进行 INNER JOIN 时,只需要 10 分钟即可完成,但我发现查询没有返回不在表 B 的 Name2 列中的行,这是一个问题,因为我需要返回它们。

4

1 回答 1

3

此查询可能会更快地返回正确的结果,或者它可能会返回不正确的结果而没有速度改进

这一切都基于 SQL Server 知识,但我假设 InnoDB 具有相同的特征。

SELECT Name 
FROM A
WHERE A.isPair = 'T'
AND NOT EXISTS (
    SELECT 1 FROM B 
    WHERE A.Name = B.Name2
    AND B.status = 'valid'
    )

我希望我已经正确地重新排列了布尔逻辑。

在您在 A 中搜索在 B 中没有匹配项或状态为 <> 有效的匹配项之前

新查询返回来自 A 的记录,它在 B 中找不到状态 = 有效的匹配项。希望这是同样的事情。

我在这里使用了两个数据库概念:

  1. 使用 EXISTS 时,它可以只查看表记录是否存在,它不必加入表并从中检索值.....尽管大多数查询计划程序会自动执行此操作,所以这是一个很长的镜头

  2. 运算符<>是不可搜索的,这意味着它不能利用任何包含该列的索引status......即它不能显式地寻找没有值的索引,它只能搜索特定值的索引. 所以我把它改成=了这个原因,也因为它支持NOT EXISTS逻辑

同样,我对 InnoDB 了解不多,但我敢肯定,如果它没有这些限制,那么 Oracle 和 Microsoft 已经复制了这些技巧。

比较查询计划将使您了解这种重写是否有任何不同。此外,比较现有 INNER 和 OUTER 查询版本之间的查询计划可能会有所帮助。

于 2014-10-27T06:45:52.013 回答