左连接似乎极大地阻碍了SQL查询性能

时间:2014-10-27 04:03:19

标签: mysql sql left-join innodb heidisql

我有两张桌子:

表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列中没有的行,这是一个问题,因为我需要它们返回。

1 个答案:

答案 0 :(得分: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中没有匹配或匹配状态&lt;&gt;的记录之前有效

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

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

  1. 当使用EXISTS时,它只能查看表记录是否存在,它不必连接到表并从中检索值......大多数查询规划器自动执行此操作,因此这是一个远射

  2. 运算符<>是不可搜索的,这意味着它无法利用包含列status的任何索引...即它无法明确地寻找缺席索引一个值,它只能搜索索引的特定值。因此我将其更改为=,因为它支持NOT EXISTS逻辑

  3. 我再一次对InnoDB了解不多,但我确信它是否没有这些限制,这些技巧已经被Oracle和微软所复制。

    比较查询计划可以让您了解此重写是否有所不同。另外,在查询的现有INNER和OUTER版本之间比较查询计划可能会对事情有所了解。