2014-11-17 56 views
0

我最近已经注意到,执行一个包含许多连接的查询比执行这些连接的执行时间要长得多。更具体地讲:SQL(tsql) - 加入

SELECT a.*, b.A, c.A, d.A 
FROM a 
LEFT JOIN 
b 
on a.A = b.A or a.B = b.A 
LEFT JOIN 
c 
on a.A = c.A or a.B = c.A 
LEFT JOIN 
d 
on a.A = d.A or a.B = d.A 

注意到时间的宇宙量完成,同时做加入的每一个步骤,并保存到一个表,真的需要很短的时间。整个查询的工作时间为1:30小时,并且完成时间不长((((a-> b) - > c) - > d)总共需要3分钟。

这是什么原因,有人可以帮忙吗?

+0

请编辑你的问题,并解释一点更好的选项,为您工作得更快。 – JotaBe

回答

0

问题不在于一般的链接join。问题是or。我建议写这篇为:

SELECT a.*, coalesce(b1.A, b2.A) as A, coalesce(c1.A, c2.A), . . . 
FROM a LEFT JOIN 
    b1 
    on a.A = b1.A LEFT JOIN 
    b2 
    on a.B = b2.A LEFT JOIN 
    c1 
    on a.A = c1.A LEFT JOIN 
    c2 
    on a.B = c2.A LEFT JOIN 
    . . . 

,如果你有在每个表中最多只有一个匹配这应返回类似的结果。如果or中的每个条件与另一行匹配,则您的版本可以生成多行。

1

检查查询计划
我怀疑你正在进入一个循环连接
它倾向于做一个循环连接,只要你有一个以上的连接条件
尝试暗示

SELECT a.*, b.A, c.A, d.A 
    FROM a 
    LEFT OUTER HASH JOIN b 
    on a.A = b.A 
    or a.B = b.A 
    LEFT OUTER HASH JOIN c 
    on a.A = c.A 
    or a.B = c.A 
    LEFT OUTER HASH JOIN d 
    on a.A = d.A 
    or a.B = d.A 

这可能工作 - 但我怀疑它

SELECT a.*, b.A, c.A, d.A 
    FROM a 
    LEFT OUTER HASH JOIN b 
    on b.A in (a.A, a.B) 
    ...