Velocidad de ejecución

17/09/2003 - 10:21 por Alberto | Informe spam
Después de realizar el producto cartesiano de dos tablas del siguiente modo:

use northwind
select *
from customers, orders

observo que tarda cierto tiempo en ofrecer la respuesta pero lo que me llama
poderosamente la atención es que si hago lo siguiente:

use northwind
select *
from customers c
inner join orders o
on c.customerid = o.customerid

tarda menos tiempo en resolverlo cuando (me imagino) internamente tiene que
hacer el producto cartesiano y después filtrar filas.
¿Alguien conoce la explicación?

Gracias.

Preguntas similare

Leer las respuestas

#6 Liliana Sorrentino
17/09/2003 - 13:56 | Informe spam
Alberto,
si me permitís, creo que puede haber una confusión con INNER JOIN y CROSS
JOIN.

INNER JOIN es la que devuelve los datos sólo si tienen una fila
correspondiente en la otra tabla, según la condición especificada en ON. En
tu caso, realizará un SCAN en la tabla de Clientes (si es que vas a mostrar
a todos) y un INDEX SEEK en la tabla de Pedidos (asumiendo que tiene
índice), buscando sólo los que cumplen la condición de igualdad.

CROSS JOIN es la que devuelve el producto cartesiano de ambas tablas.

Si pudieras ver el Plan de Ejecución de ambas consultas quedaría clara la
diferencia.
Saludos... Liliana.


"Alberto" escribió en el mensaje
news:
Insisto, creo que no me estais entendiendo.

Que el producto cartesiano devuelve muchísimas más filas (75530 en


concreto)
por 830 cuando se hace la unión de clientes con sus pedidos ya lo sé.
La pregunta es: ¿cómo une sql server las filas de las dos tablas cuando se
hace el inner join? ¿no tiene que juntar todas las filas con todas y


después
eliminar las que no coincidan (clientes con sus pedidos)?


"Rubén Vigón" escribió en el mensaje
news:%
> Lo que ocurre es que si utilizas un producto cartesiano (es decir, no
utilizas INNER JOIN o un WHERE
> por el campo de relación) cada registro de la tabla Clientes "enlazaría"
con todos y cada uno de los
> registros de la tabla Pedidos, en lugar de enlazar sólo con "sus"


pedidos,
lo que genera un volumen
> de registros MUY superior
>
> Por ejemplo, supongamos 5 clientes con 8 pedidos cada uno
>
> SELECT * FROM Clientes, Pedidos
> Devolvería 200 registros (5 registros de la tabla Clientes* 40 registros
de la tabla Pedidos)
> Incorrecto!
>
> SELECT * FROM Clientes INNER JOIN Pedidos ON Clientes.IdCliente > Pedidos.IdCliente
> Devolvería sólo 40 registros (correcto!)
>
> Además, no sólo se obtiene un volumen de registros muy superior, sino


que
gran parte de éstos
> registros serían "incorrectos", ya que mostrarían pedidos de otros
clientes
>
> Un saludo!
>
> Rubén Vigón
> Microsoft MVP Visual Basic
>
>


Respuesta Responder a este mensaje
#7 Mariano Alvarez
18/09/2003 - 06:05 | Informe spam
La respuesta es muy simple.

Tu imaginas que para resolver el inner join el SQL primero hace el cross
join y luego aplica el filtro. Te diria que casi nunca usa esa opcion.

El SQL tiene basicamente tres estrategias de join que usa de acuerdo a si
los datos son mucho o pocos, si estan previamente ordenados o desordenados,
si le conviene tenerlos ordenados para el paso siquiente del plan, etc.
Estas estrategias son MERGE JOIN para lo cual ambos conjuntos de entrada
deben estar ordenados y el orden del algoritmo es O(N) donde N es el numero
de elementos del conjunto mas grande, HASH JOIN que requiere el calculo de
un hash y es el siguiente en velocidad y NESTED LOOP que es el mas lento ya
que por cada elemento de el primer conjunto que selecciona va a buscar los
elementos del segundo conjunto y suele ser muy usado por el optimizador
cuando hay pocos registros y era el unico que habia en versiones anteriores
del SQL. Pos supuesto que lo que te comento es una simplificacion ya que es
algo mas complejo que esto.



Jose Mariano Alvarez
Comunidad de base de datos
Grupo de Usuarios Microsoft
www.mug.org.ar


"Alberto" wrote in message
news:
Insisto, creo que no me estais entendiendo.

Que el producto cartesiano devuelve muchísimas más filas (75530 en


concreto)
por 830 cuando se hace la unión de clientes con sus pedidos ya lo sé.
La pregunta es: ¿cómo une sql server las filas de las dos tablas cuando se
hace el inner join? ¿no tiene que juntar todas las filas con todas y


después
eliminar las que no coincidan (clientes con sus pedidos)?


"Rubén Vigón" escribió en el mensaje
news:%
> Lo que ocurre es que si utilizas un producto cartesiano (es decir, no
utilizas INNER JOIN o un WHERE
> por el campo de relación) cada registro de la tabla Clientes "enlazaría"
con todos y cada uno de los
> registros de la tabla Pedidos, en lugar de enlazar sólo con "sus"


pedidos,
lo que genera un volumen
> de registros MUY superior
>
> Por ejemplo, supongamos 5 clientes con 8 pedidos cada uno
>
> SELECT * FROM Clientes, Pedidos
> Devolvería 200 registros (5 registros de la tabla Clientes* 40 registros
de la tabla Pedidos)
> Incorrecto!
>
> SELECT * FROM Clientes INNER JOIN Pedidos ON Clientes.IdCliente > Pedidos.IdCliente
> Devolvería sólo 40 registros (correcto!)
>
> Además, no sólo se obtiene un volumen de registros muy superior, sino


que
gran parte de éstos
> registros serían "incorrectos", ya que mostrarían pedidos de otros
clientes
>
> Un saludo!
>
> Rubén Vigón
> Microsoft MVP Visual Basic
>
>


email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida