2012-01-25 21 views
5

Me encontré con esta situación muy extraña, y pensé que la lanzaría a la multitud para descubrir el POR QUÉ.INNER JOIN en Linked Server Tabla mucho más lenta que Sub-Query

Tengo una consulta que se une a una tabla en un servidor vinculado:

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) 

esta consulta se refería siempre (ni siquiera descubierto el tiempo de ejecución real), y es entonces cuando me di cuenta de B no tenía índice, así que lo agregué, pero eso no solucionó el problema. Por último, de la desesperación traté:

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

Esta versión de la consulta, en mi mente como mínimo, deben tener los mismos resultados, pero he aquí que, su respuesta inmediata!

¿Alguna idea de por qué uno se bloquea y el otro proceso rápidamente? Y sí, esperé para asegurarme de que el índice había sido creado antes de ejecutar ambos.

+0

¿Has mirado el plan de ejecución para ambos? ¿Difieren? ¿Expediste un _dbcc dropcleanbuffers_ entre cada método? – canon

+0

Aproximadamente ¿cuántos registros hay en 'remote.B'? – Yuck

+0

La base de datos "remota" está en otro servidor al que se accede a través de un servidor de enlaces y hay alrededor de 600 filas. – Limey

Respuesta

4

es porque a veces (muy a menudo) planes de ejecución generado automáticamente por El motor de servidor sql no es tan bueno y obvio como deseamos. Puede ver el plan de ejecución en ambas situaciones. Sugiero usar la sugerencia en la primera consulta, algo así: INNER MERGE JOIN.

Aquí hay más información sobre lo siguiente:

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

+0

¡Esto es algo nuevo y agradable que aprendí hoy! Conozco otros lugares en los que puedo usar este tipo de fusión. – Limey

+0

Estoy usando una combinación de fusión para unir vista (creada a partir de 3 tablas) y tabla. La vista ya tiene un plan de ejecución, pero incluso ese motor crea algo nuevo, mucho más lento. Ese es otro caso cuando puedes encontrarlo útil. – devarc

+3

'MERGE' no es una sugerencia mágica de" ir más rápido ". Si no está obteniendo el plan correcto, es mejor primero entender por qué. –

1

¿La tabla remota no está en ese servidor? ¿Es posible que la unión realice múltiples llamadas a la tabla remota mientras que la subconsulta realiza una única solicitud de copia de los datos de la tabla, lo que resulta en menos tiempo de espera en la red?

+0

'~ 600' filas en la tabla remota. Encuentre algo que respalde la idea de que la subconsulta está dando como resultado que toda la tabla esté almacenada en la memoria caché y esto obtiene mi +1 – Yuck

+0

El plan de ejecución estimado muestra que solo tiene acceso a él una vez en ambas versiones de la consulta. El malo se estima utilizando el 40% del procesamiento, mientras que el 2º es el 1% – Limey

+0

Limey, ¿cuál es la redacción exacta en el plan de ejecución? Me sorprendería si realmente indica la cantidad de llamadas que se hicieron internas al proceso. –

3

Para servidores vinculados segunda variante prefetches todos los datos a nivel local y hacer las unen, desde el 1 de variante puede hacer inner loop join ida y vuelta al servidor vinculado para cada fila en A

+0

@Limey para la primera variante de ** Número de ejecuciones ** en el plan de consulta para llamadas remotas; si es más de 1, entonces ** sí ** roundtripd para los datos –

+0

Comprobó el plan de ejecución estimado; su lazo no interno se une a esa mesa. – Limey

+1

@Liney - ¿Cuál es el ** Número de ejecuciones ** para el elemento de la tabla remota? O muéstrenos todo el plan de consulta como XML –

1

sólo voy a tener una conjetura aquí. Cuando accede a remote.b, ¿es una tabla en otro servidor?

Si lo es, la razón por la que la segunda consulta es más rápida es porque hace una consulta al otro servidor y obtiene todos los campos que necesita de b, antes de procesar los datos. En la primera consulta, procesa datos y al mismo tiempo realiza varias solicitudes al otro servidor.

Espero que esto te ayude.