2012-01-25 15 views
5

Mi sono imbattuto in questa situazione molto strana, e ho pensato di gettarlo tra la folla per scoprire il perché.JOIN INTERNO su Server Server Tabella molto più lento di Sub-Query

Ho una domanda che è stata unisce una tabella in un server collegato:

select a.*, b.phone 
from table_a a, 
join remote.table_b b on b.id = a.id 
(lots of data on A, but very few on B) 

questa query stava parlando sempre (mai scoperto il tempo di esecuzione reale), e cioè quando ho notato B avuto indice, quindi l'ho aggiunto, ma ciò non ha risolto il problema. Infine, per disperazione ho provato:

select a.*, b.phone 
from table_a a, 
join (select id, phone from remote.B) as b on b.id = a.id 

Questa versione della query, nella mia mente come minimo, dovrebbe avere gli stessi risultati, ma ecco, il suo rispondere immediatamente!

Qualche idea sul perché uno si bloccherebbe e l'altro processo rapidamente? E sì, ho aspettato per assicurarmi che l'indice fosse stato costruito prima di eseguirli entrambi.

+0

Hai esaminato il piano di esecuzione per entrambi? Differiscono? Hai emesso _dbcc dropcleanbuffers_ tra ogni metodo? – canon

+0

Circa il numero di record in 'remote.B'? – Yuck

+0

Il DB "remoto" si trova su un altro server a cui si accede tramite un server di collegamento e ci sono circa 600 righe. – Limey

risposta

4

E 'perché a volte (molto spesso) piani di esecuzione automaticamente generato da Il motore SQL Server non è così buono e ovvio come vogliamo. Puoi guardare il piano di esecuzione in entrambe le situazioni. Suggerisco di usare il suggerimento nella prima query, qualcosa del genere: UNNER MERGE JOIN.

Ecco qualche informazione in più su questo:

http://msdn.microsoft.com/en-us/library/ms181714.aspx

+0

Questa è una bella novità che ho imparato oggi! Conosco altri posti in cui posso utilizzare questo tipo di unione. – Limey

+0

Sto usando un suggerimento di unione per unire la vista (creata da 3 tabelle) e la tabella. View ha già un piano di esecuzione ma anche quel motore crea nuovo, molto più lentamente. Questo è un altro caso in cui puoi trovarlo utile. – devarc

+3

'MERGE' non è un suggerimento magico" vai più veloce ". Se non stai ottenendo il piano giusto, è meglio prima capire perché. –

1

Tabella remota come non su quel server? È possibile che il join stia effettivamente effettuando più chiamate verso la tabella remota mentre la sottoquery sta effettuando una singola richiesta per una copia dei dati della tabella, con conseguente minor tempo di attesa sulla rete?

+0

. Trova qualcosa che supporti l'idea che la sottoquery stia ottenendo l'intera tabella nella cache e questo ottenga il mio +1 – Yuck

+0

Il piano di esecuzione stimato mostra di accedervi solo una volta in entrambe le versioni della query. La cattiva è stimata usando il 40% dell'elaborazione, mentre la seconda è 1% – Limey

+0

Limey, qual è la dicitura esatta nel piano di esecuzione? Sarei sorpreso se in realtà indichi il numero di chiamate che sono state rese interne al processo. –

3

Per i server collegati seconda variante precaricamenti tutti i dati in locale e fare il join, dal 1 ° variante può fare inner loop join andata e ritorno al server collegato per ogni riga di una

+0

@Limey per la prima variante di ** Numero di esecuzioni ** in Piano di query per chiamate remote - se è superiore a 1, allora ** fa ** roundtripd per i dati –

+0

Controllato il piano di esecuzione stimato; il suo ciclo interno non si unisce a quel tavolo. – Limey

+1

@Liney - Qual è il ** numero di esecuzioni ** per l'elemento della tabella remota? Oppure mostraci l'intero piano di query come XML –

1

Sto solo andando ad avere una supposizione qui. Quando accedi a remote.b è una tabella su un altro server?

Se lo è, il motivo per cui la seconda query è più veloce è perché, si esegue una query all'altro server e si ottengono tutti i campi necessari da b, prima di elaborare i dati. Nella prima query si stanno elaborando dati e contemporaneamente si stanno facendo diverse richieste all'altro server.

Spero che questo ti aiuti.