2014-11-17 4 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: 30h и не был близок к завершению, в то время как (((a-> b) -> c) -> d) выполнялся в целом как 3 минуты.

В чем причина этого, может ли кто-нибудь помочь?

+0

Пожалуйста, отредактируйте ваш вопрос и объясните немного лучше вариант, который работал быстрее для вас. – JotaBe

ответ

0

Проблема не в цепи join s в целом. Проблема заключается в том, что 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) 
    ... 
Смежные вопросы