2012-05-21 26 views
5

Nella mia query sono presenti 4 join full-outer ed è molto lento, quindi l'ordine di FULL OUTER JOIN fa una differenza in termini di prestazioni/risultato?SQL Server: l'ordine del full outer join è importante?

full outer join = ⋈

Poi,

Ho una situazione: A ⋈ B ⋈ C ⋈ D

Tutto si unisce verifica su un comune chiave di tutto k contenuta in tutti A, B, C, D

Poi:

  • Cambiare l'ordine di ⋈ join può fare la differenza per le prestazioni?
  • Cambiando l'ordine di ⋈ si modifica il risultato?

Sento che non dovrebbe influenzare il risultato, ma influenzerà le prestazioni o non ne sono sicuro!

Aggiornamento:

Will SQL Server riorganizzare automaticamente i join per migliorare le prestazioni assumendo il set di risultati sarà indipendente dall'ordine?

+1

Il risultato dovrebbe essere lo stesso. È abbastanza facile controllare le prestazioni. Confronta il tempo necessario quando ordini le tabelle da pochi a molti successi nell'ordine inverso. –

+0

Perché non provarlo? Guarda i piani di esecuzione e le tracce di SQL Profiler per le diverse combo? – EBarr

+0

Quando dici un ordine diverso, intendi: '(a FULL JOIN b) FULL JOIN c' vs' a FULL JOIN (b FULL JOIN c) 'ad esempio? –

risposta

8

No, la riorganizzazione degli ordini JOIN non dovrebbe influire sulle prestazioni. MSSQL (come con altri DBMS) ha un query optimizer il cui lavoro è quello di trovare il piano di query più efficiente per qualsiasi query. Generalmente, fanno un buon lavoro - quindi è improbabile che battano facilmente l'ottimizzatore.

Detto questo, si sbagliano di tanto in tanto. È qui che entra in gioco reading an execution plan. È possibile aggiungere JOIN hints per comunicare a MSSQL come unire le proprie tabelle (a questo punto, l'ordine corrisponde a). Ordinerai generalmente dalla tabella più piccola a quella più grande (anche se, con uno FULL JOIN, non è probabile che importi molto) e segui lo rules of thumb per i tipi di join.

Dato che stai facendo FULL JOINS, stai praticamente leggendo la totalità delle 4 tabelle dal disco. È probabile che sia molto costoso. Potresti voler riesaminare il problema e vedere se può essere realizzato in un modo diverso.

+1

+1: All'OP - È importante notare che SQL non viene eseguito in modo nativo e ingenuo. In realtà è solo un'espressione algorthmica per dire all'ottimizzatore la descrizione funzionale del problema. L'ottimizzatore quindi lo compila in modo efficace ed esegue un piano che può essere considerato quasi completamente indipendente da SQL. – MatBailie

0

La modifica dell'ordine di un join esterno completo non deve influire sulle prestazioni o sui risultati. L'unica cosa che verrà influenzata in base all'ordine di un Full Outer Join è l'ordine predefinito delle colonne prodotte se si utilizza un SELECT *. Potresti avere problemi di prestazioni semplicemente provando a fare più join con tabelle di grandi dimensioni. Se non esiste una clausola where per limitare le tabelle, potresti ottenere centinaia di migliaia di risultati.

3
  • Cambiando l'ordine di ⋈ si modifica il risultato?

No, l'ordine di FULL JOIN non ha importanza, il risultato sarà lo stesso. Si noti tuttavia, che non si può usare qualcosa di simile (ciò che segue può dare risultati diversi a seconda dell'ordine di join):

SELECT 
    COALESCE(a.id, b.id, c.id, d.id) AS id, --- Key columns used in FULL JOIN 
    a.*, b.*, c.*, d.*      --- other columns     
FROM a 
    FULL JOIN b 
     ON b.id = a.id 
    FULL JOIN c 
     ON c.id = a.id 
    FULL JOIN d 
     ON d.id = a.id ; 

Devi usare qualcosa di simile (nessuna differenza nei risultati qualunque sia l'ordine di join):

SELECT 
    COALESCE(a.id, b.id, c.id, d.id) AS id, 
    a.*, b.*, c.*, d.*         
FROM a 
    FULL JOIN b 
     ON b.id = a.id 
    FULL JOIN c 
     ON c.id = COALESCE(a.id, b.id) 
    FULL JOIN d 
     ON d.id = COALESCE(a.id, b.id, c.id) ; 

  • L'ordine di ⋈ join potrebbe cambiare in base alle prestazioni?

Prendendo in considerazione il fatto che la seconda e la terza si unisce deve essere fatto sulla COALESCE() delle colonne e non le colonne stesse, io soltanto il test con tabelle di grandi dimensioni abbastanza mostrerà se gli indici possono essere utilizzati efficacemente.

+0

Non ho nessuna situazione di coalescenza. Inoltre, vedi l'aggiornamento nella domanda! –

+0

@ Yugal: Che cosa intendi con questo? Puoi pubblicare 2 versioni della tua query in modo che capiamo cosa intendi? Come ti iscrivi se non usi 'COALESCE()'? –

+0

Hm .. qualcosa come '(A ⋈ B su A.sp = B.sp) ⋈ C su A.sp = C.sp' e così via .. –